Commit a76c352d authored by xster's avatar xster Committed by GitHub

Add Cupertino to gallery and add CupertinoButton and many yak friends (#8411)

* Add cupertino to gallery and add CupertinoButto

* Use single quotes

* Add disabled state

* Some review notes

* Make button animation more responsive and tweak timing

* Renamed things Cupertino

* Button with background, move cupertino demos, move material demos

* Move 2 level list too

* Refactor various demo route names

* Some review notes

* More reviews and add test

* Linter as

* Move private constant up
parent 9dec5f90
...@@ -2,37 +2,11 @@ ...@@ -2,37 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
export 'bottom_navigation_demo.dart';
export 'buttons_demo.dart';
export 'calculator_demo.dart'; export 'calculator_demo.dart';
export 'cards_demo.dart';
export 'chip_demo.dart';
export 'colors_demo.dart'; export 'colors_demo.dart';
export 'contacts_demo.dart'; export 'contacts_demo.dart';
export 'data_table_demo.dart';
export 'date_and_time_picker_demo.dart';
export 'dialog_demo.dart';
export 'drawer_demo.dart';
export 'expansion_panels_demo.dart';
export 'grid_list_demo.dart';
export 'icons_demo.dart';
export 'leave_behind_demo.dart';
export 'list_demo.dart';
export 'menu_demo.dart';
export 'modal_bottom_sheet_demo.dart';
export 'overscroll_demo.dart';
export 'page_selector_demo.dart';
export 'persistent_bottom_sheet_demo.dart';
export 'pesto_demo.dart'; export 'pesto_demo.dart';
export 'progress_indicator_demo.dart';
export 'scrollable_tabs_demo.dart';
export 'selection_controls_demo.dart';
export 'shrine_demo.dart'; export 'shrine_demo.dart';
export 'slider_demo.dart';
export 'snack_bar_demo.dart';
export 'tabs_demo.dart';
export 'tabs_fab_demo.dart';
export 'text_field_demo.dart';
export 'tooltip_demo.dart';
export 'two_level_list_demo.dart';
export 'typography_demo.dart'; export 'typography_demo.dart';
export 'cupertino/cupertino.dart';
export 'material/material.dart';
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export 'cupertino_activity_indicator_demo.dart';
export 'cupertino_buttons_demo.dart';
export 'cupertino_dialog_demo.dart';
export 'cupertino_slider_demo.dart';
export 'cupertino_switch_demo.dart';
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoProgressIndicatorDemo extends StatelessWidget {
static const String routeName = '/cupertino/progress_indicator';
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cupertino Activity Indicator'),
),
body: new Center(
child: new CupertinoActivityIndicator(),
),
);
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoButtonsDemo extends StatefulWidget {
static const String routeName = '/cupertino/buttons';
@override
_CupertinoButtonDemoState createState() => new _CupertinoButtonDemoState();
}
class _CupertinoButtonDemoState extends State<CupertinoButtonsDemo> {
int _pressedCount = 0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cupertino Buttons'),
),
body: new Column(
children: <Widget> [
new Padding(
padding: const EdgeInsets.all(16.0),
child: new Text('iOS themed buttons are flat. They can have borders or backgrounds but '
'only when necessary.'),
),
new Expanded(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
new Text(_pressedCount > 0 ? "Button pressed $_pressedCount times" : " "),
new Padding(padding: const EdgeInsets.all(12.0)),
new Align(
alignment: const FractionalOffset(0.5, 0.4),
child: new Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new CupertinoButton(
child: new Text('Cupertino Button'),
onPressed: () {
setState(() {_pressedCount++;});
}
),
new CupertinoButton(
child: new Text('Disabled'),
onPressed: null,
),
],
),
),
new Padding(padding: const EdgeInsets.all(12.0)),
new CupertinoButton(
child: new Text('With Background'),
color: CupertinoButton.kBlue,
onPressed: () {
setState(() {_pressedCount++;});
}
),
new Padding(padding: const EdgeInsets.all(12.0)),
new CupertinoButton(
child: new Text('Disabled'),
color: CupertinoButton.kBlue,
onPressed: null,
),
],
)
),
],
)
);
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoDialogDemo extends StatefulWidget {
static const String routeName = '/cupertino/dialog';
@override
_CupertinoDialogDemoState createState() => new _CupertinoDialogDemoState();
}
class _CupertinoDialogDemoState extends State<CupertinoDialogDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
void showDemoDialog<T>({ BuildContext context, Widget child }) {
showDialog<T>(
context: context,
child: child,
barrierDismissable: false,
)
.then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You selected: $value')
));
}
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Cupertino Dialogs'),
),
body: new ListView(
padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 72.0),
children: <Widget> [
new CupertinoButton(
child: new Text('Alert'),
color: CupertinoButton.kBlue,
onPressed: () {
showDemoDialog<String>(
context: context,
child: new CupertinoAlertDialog(
content: new Text('Discard draft?'),
actions: <Widget>[
new CupertinoDialogAction(
child: new Text('Discard'),
isDestructive: true,
onPressed: () { Navigator.pop(context, 'OK'); }
),
new CupertinoDialogAction(
child: new Text('Cancel', style: new TextStyle(fontWeight: FontWeight.w600)),
onPressed: () { Navigator.pop(context, 'Cancel'); }
),
]
),
);
},
),
new Padding(padding: const EdgeInsets.all(8.0)),
new CupertinoButton(
child: new Text('Alert with Title'),
color: CupertinoButton.kBlue,
onPressed: () {
showDemoDialog<String>(
context: context,
child: new CupertinoAlertDialog(
title: new Text('Allow "Maps" to access your location while you use the app?'),
content: new Text(
'Your current location will be displayed on the map and used for directions, '
'nearby search results, and estimated travel times.'
),
actions: <Widget>[
new CupertinoDialogAction(
child: new Text('Don\'t Allow'),
onPressed: () { Navigator.pop(context, 'Disallow'); }
),
new CupertinoDialogAction(
child: new Text('Allow'),
onPressed: () { Navigator.pop(context, 'Allow'); }
),
]
),
);
},
),
],
),
);
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoSliderDemo extends StatefulWidget {
static const String routeName = '/cupertino/slider';
@override
_CupertinoSliderDemoState createState() => new _CupertinoSliderDemoState();
}
class _CupertinoSliderDemoState extends State<CupertinoSliderDemo> {
double _value = 25.0;
double _discreteValue = 20.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cupertino Sliders'),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
new CupertinoSlider(
value: _value,
min: 0.0,
max: 100.0,
onChanged: (double value) {
setState(() {
_value = value;
});
}
),
new Text('Cupertino Continuous'),
]
),
new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
new CupertinoSlider(
value: _discreteValue,
min: 0.0,
max: 100.0,
divisions: 5,
onChanged: (double value) {
setState(() {
_discreteValue = value;
});
}
),
new Text('Cupertino Discrete'),
]
),
],
),
),
);
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CupertinoSwitchDemo extends StatefulWidget {
static const String routeName = '/cupertino/switch';
@override
_CupertinoSwitchDemoState createState() => new _CupertinoSwitchDemoState();
}
class _CupertinoSwitchDemoState extends State<CupertinoSwitchDemo> {
bool _switchValue = false;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Cupertino Switch'),
),
body: new Center(
child: new CupertinoSwitch(
value: _switchValue,
onChanged: (bool value) {
setState(() {
_switchValue = value;
});
}
),
),
);
}
}
...@@ -79,7 +79,7 @@ class CustomIcon extends StatelessWidget { ...@@ -79,7 +79,7 @@ class CustomIcon extends StatelessWidget {
} }
class BottomNavigationDemo extends StatefulWidget { class BottomNavigationDemo extends StatefulWidget {
static const String routeName = '/bottom_navigation'; static const String routeName = '/material/bottom_navigation';
@override @override
_BottomNavigationDemoState createState() => new _BottomNavigationDemoState(); _BottomNavigationDemoState createState() => new _BottomNavigationDemoState();
......
...@@ -4,43 +4,43 @@ ...@@ -4,43 +4,43 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../gallery/demo.dart'; import '../../gallery/demo.dart';
const String _raisedText = const String _raisedText =
"Raised buttons add dimension to mostly flat layouts. They emphasize " 'Raised buttons add dimension to mostly flat layouts. They emphasize '
"functions on busy or wide spaces."; 'functions on busy or wide spaces.';
const String _raisedCode = 'buttons_raised'; const String _raisedCode = 'buttons_raised';
const String _flatText = "A flat button displays an ink splash on press " const String _flatText = 'A flat button displays an ink splash on press '
"but does not lift. Use flat buttons on toolbars, in dialogs and " 'but does not lift. Use flat buttons on toolbars, in dialogs and '
"inline with padding"; 'inline with padding';
const String _flatCode = 'buttons_flat'; const String _flatCode = 'buttons_flat';
const String _dropdownText = const String _dropdownText =
"A dropdown button displays a menu that's used to select a value from a " 'A dropdown button displays a menu that\'s used to select a value from a '
"small set of values. The button displays the current value and a down " 'small set of values. The button displays the current value and a down '
"arrow."; 'arrow.';
const String _dropdownCode = 'buttons_dropdown'; const String _dropdownCode = 'buttons_dropdown';
const String _iconText = const String _iconText =
"IconButtons are appropriate for toggle buttons that allow a single choice " 'IconButtons are appropriate for toggle buttons that allow a single choice '
"to be selected or deselected, such as adding or removing an item's star."; 'to be selected or deselected, such as adding or removing an item\'s star.';
const String _iconCode = 'buttons_icon'; const String _iconCode = 'buttons_icon';
const String _actionText = const String _actionText =
"Floating action buttons are used for a promoted action. They are " 'Floating action buttons are used for a promoted action. They are '
"distinguished by a circled icon floating above the UI and can have motion " 'distinguished by a circled icon floating above the UI and can have motion '
"behaviors that include morphing, launching, and a transferring anchor " 'behaviors that include morphing, launching, and a transferring anchor '
"point."; 'point.';
const String _actionCode = 'buttons_action'; const String _actionCode = 'buttons_action';
class ButtonsDemo extends StatefulWidget { class ButtonsDemo extends StatefulWidget {
static const String routeName = '/buttons'; static const String routeName = '/material//buttons';
@override @override
_ButtonsDemoState createState() => new _ButtonsDemoState(); _ButtonsDemoState createState() => new _ButtonsDemoState();
......
...@@ -126,7 +126,7 @@ class TravelDestinationItem extends StatelessWidget { ...@@ -126,7 +126,7 @@ class TravelDestinationItem extends StatelessWidget {
} }
class CardsDemo extends StatelessWidget { class CardsDemo extends StatelessWidget {
static const String routeName = '/cards'; static const String routeName = '/material/cards';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ChipDemo extends StatefulWidget { class ChipDemo extends StatefulWidget {
static const String routeName = '/chip'; static const String routeName = '/material/chip';
@override @override
_ChipDemoState createState() => new _ChipDemoState(); _ChipDemoState createState() => new _ChipDemoState();
......
...@@ -141,7 +141,7 @@ class DessertDataSource extends DataTableSource { ...@@ -141,7 +141,7 @@ class DessertDataSource extends DataTableSource {
} }
class DataTableDemo extends StatefulWidget { class DataTableDemo extends StatefulWidget {
static const String routeName = '/data-table'; static const String routeName = '/material/data-table';
@override @override
_DataTableDemoState createState() => new _DataTableDemoState(); _DataTableDemoState createState() => new _DataTableDemoState();
......
...@@ -110,7 +110,7 @@ class _DateTimePicker extends StatelessWidget { ...@@ -110,7 +110,7 @@ class _DateTimePicker extends StatelessWidget {
} }
class DateAndTimePickerDemo extends StatefulWidget { class DateAndTimePickerDemo extends StatefulWidget {
static const String routeName = '/date-and-time-pickers'; static const String routeName = '/material/date-and-time-pickers';
@override @override
_DateAndTimePickerDemoState createState() => new _DateAndTimePickerDemoState(); _DateAndTimePickerDemoState createState() => new _DateAndTimePickerDemoState();
......
...@@ -47,7 +47,7 @@ class DialogDemoItem extends StatelessWidget { ...@@ -47,7 +47,7 @@ class DialogDemoItem extends StatelessWidget {
} }
class DialogDemo extends StatefulWidget { class DialogDemo extends StatefulWidget {
static const String routeName = '/dialog'; static const String routeName = '/material/dialog';
@override @override
DialogDemoState createState() => new DialogDemoState(); DialogDemoState createState() => new DialogDemoState();
...@@ -68,7 +68,7 @@ class DialogDemoState extends State<DialogDemo> { ...@@ -68,7 +68,7 @@ class DialogDemoState extends State<DialogDemo> {
void showDemoDialog<T>({ BuildContext context, Widget child }) { void showDemoDialog<T>({ BuildContext context, Widget child }) {
showDialog<T>( showDialog<T>(
context: context, context: context,
child: child child: child,
) )
.then<Null>((T value) { // The value passed to Navigator.pop() or null. .then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) { if (value != null) {
...@@ -195,7 +195,7 @@ class DialogDemoState extends State<DialogDemo> { ...@@ -195,7 +195,7 @@ class DialogDemoState extends State<DialogDemo> {
builder: (BuildContext context) => new FullScreenDialogDemo() builder: (BuildContext context) => new FullScreenDialogDemo()
)); ));
} }
) ),
] ]
// Add a little space between the buttons // Add a little space between the buttons
.map((Widget button) { .map((Widget button) {
......
...@@ -9,7 +9,7 @@ const String _kAsset1 = 'packages/flutter_gallery_assets/shrine/vendors/16c477b. ...@@ -9,7 +9,7 @@ const String _kAsset1 = 'packages/flutter_gallery_assets/shrine/vendors/16c477b.
const String _kAsset2 = 'packages/flutter_gallery_assets/shrine/vendors/sandra-adams.jpg'; const String _kAsset2 = 'packages/flutter_gallery_assets/shrine/vendors/sandra-adams.jpg';
class DrawerDemo extends StatefulWidget { class DrawerDemo extends StatefulWidget {
static const String routeName = '/drawer'; static const String routeName = '/material/drawer';
@override @override
_DrawerDemoState createState() => new _DrawerDemoState(); _DrawerDemoState createState() => new _DrawerDemoState();
......
...@@ -170,7 +170,7 @@ class DemoItem<T> { ...@@ -170,7 +170,7 @@ class DemoItem<T> {
} }
class ExpasionPanelsDemo extends StatefulWidget { class ExpasionPanelsDemo extends StatefulWidget {
static const String routeName = '/expansion_panels'; static const String routeName = '/material/expansion_panels';
@override @override
_ExpansionPanelsDemoState createState() => new _ExpansionPanelsDemoState(); _ExpansionPanelsDemoState createState() => new _ExpansionPanelsDemoState();
......
...@@ -232,7 +232,7 @@ class GridDemoPhotoItem extends StatelessWidget { ...@@ -232,7 +232,7 @@ class GridDemoPhotoItem extends StatelessWidget {
class GridListDemo extends StatefulWidget { class GridListDemo extends StatefulWidget {
GridListDemo({ Key key }) : super(key: key); GridListDemo({ Key key }) : super(key: key);
static const String routeName = '/grid-list'; static const String routeName = '/material/grid-list';
@override @override
GridListDemoState createState() => new GridListDemoState(); GridListDemoState createState() => new GridListDemoState();
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class IconsDemo extends StatefulWidget { class IconsDemo extends StatefulWidget {
static const String routeName = '/icons'; static const String routeName = '/material/icons';
@override @override
IconsDemoState createState() => new IconsDemoState(); IconsDemoState createState() => new IconsDemoState();
......
...@@ -31,7 +31,7 @@ class LeaveBehindItem implements Comparable<LeaveBehindItem> { ...@@ -31,7 +31,7 @@ class LeaveBehindItem implements Comparable<LeaveBehindItem> {
class LeaveBehindDemo extends StatefulWidget { class LeaveBehindDemo extends StatefulWidget {
LeaveBehindDemo({ Key key }) : super(key: key); LeaveBehindDemo({ Key key }) : super(key: key);
static const String routeName = '/leave-behind'; static const String routeName = '/material/leave-behind';
@override @override
LeaveBehindDemoState createState() => new LeaveBehindDemoState(); LeaveBehindDemoState createState() => new LeaveBehindDemoState();
......
...@@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; ...@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
class ListDemo extends StatefulWidget { class ListDemo extends StatefulWidget {
ListDemo({ Key key }) : super(key: key); ListDemo({ Key key }) : super(key: key);
static const String routeName = '/list'; static const String routeName = '/material/list';
@override @override
_ListDemoState createState() => new _ListDemoState(); _ListDemoState createState() => new _ListDemoState();
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export 'bottom_navigation_demo.dart';
export 'buttons_demo.dart';
export 'cards_demo.dart';
export 'chip_demo.dart';
export 'data_table_demo.dart';
export 'date_and_time_picker_demo.dart';
export 'dialog_demo.dart';
export 'drawer_demo.dart';
export 'expansion_panels_demo.dart';
export 'grid_list_demo.dart';
export 'icons_demo.dart';
export 'leave_behind_demo.dart';
export 'list_demo.dart';
export 'menu_demo.dart';
export 'modal_bottom_sheet_demo.dart';
export 'overscroll_demo.dart';
export 'page_selector_demo.dart';
export 'persistent_bottom_sheet_demo.dart';
export 'progress_indicator_demo.dart';
export 'scrollable_tabs_demo.dart';
export 'selection_controls_demo.dart';
export 'slider_demo.dart';
export 'snack_bar_demo.dart';
export 'tabs_demo.dart';
export 'tabs_fab_demo.dart';
export 'text_field_demo.dart';
export 'tooltip_demo.dart';
export 'two_level_list_demo.dart';
...@@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; ...@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
class MenuDemo extends StatefulWidget { class MenuDemo extends StatefulWidget {
MenuDemo({ Key key }) : super(key: key); MenuDemo({ Key key }) : super(key: key);
static const String routeName = '/menu'; static const String routeName = '/material/menu';
@override @override
MenuDemoState createState() => new MenuDemoState(); MenuDemoState createState() => new MenuDemoState();
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ModalBottomSheetDemo extends StatelessWidget { class ModalBottomSheetDemo extends StatelessWidget {
static const String routeName = '/modal-bottom-sheet'; static const String routeName = '/material/modal-bottom-sheet';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -11,7 +11,7 @@ enum IndicatorType { overscroll, refresh } ...@@ -11,7 +11,7 @@ enum IndicatorType { overscroll, refresh }
class OverscrollDemo extends StatefulWidget { class OverscrollDemo extends StatefulWidget {
OverscrollDemo({ Key key }) : super(key: key); OverscrollDemo({ Key key }) : super(key: key);
static const String routeName = '/overscroll'; static const String routeName = '/material/overscroll';
@override @override
OverscrollDemoState createState() => new OverscrollDemoState(); OverscrollDemoState createState() => new OverscrollDemoState();
......
...@@ -63,7 +63,7 @@ class _PageSelector extends StatelessWidget { ...@@ -63,7 +63,7 @@ class _PageSelector extends StatelessWidget {
} }
class PageSelectorDemo extends StatelessWidget { class PageSelectorDemo extends StatelessWidget {
static const String routeName = '/page-selector'; static const String routeName = '/material/page-selector';
static final List<IconData> icons = <IconData>[ static final List<IconData> icons = <IconData>[
Icons.event, Icons.event,
Icons.home, Icons.home,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class PersistentBottomSheetDemo extends StatefulWidget { class PersistentBottomSheetDemo extends StatefulWidget {
static const String routeName = '/persistent-bottom-sheet'; static const String routeName = '/material/persistent-bottom-sheet';
@override @override
_PersistentBottomSheetDemoState createState() => new _PersistentBottomSheetDemoState(); _PersistentBottomSheetDemoState createState() => new _PersistentBottomSheetDemoState();
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class ProgressIndicatorDemo extends StatefulWidget { class ProgressIndicatorDemo extends StatefulWidget {
static const String routeName = '/progress-indicator'; static const String routeName = '/material/progress-indicator';
@override @override
_ProgressIndicatorDemoState createState() => new _ProgressIndicatorDemoState(); _ProgressIndicatorDemoState createState() => new _ProgressIndicatorDemoState();
......
...@@ -26,7 +26,7 @@ final List<_Page> _allPages = <_Page>[ ...@@ -26,7 +26,7 @@ final List<_Page> _allPages = <_Page>[
]; ];
class ScrollableTabsDemo extends StatefulWidget { class ScrollableTabsDemo extends StatefulWidget {
static const String routeName = '/scrollable-tabs'; static const String routeName = '/material/scrollable-tabs';
@override @override
ScrollableTabsDemoState createState() => new ScrollableTabsDemoState(); ScrollableTabsDemoState createState() => new ScrollableTabsDemoState();
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../gallery/demo.dart'; import '../../gallery/demo.dart';
const String _checkboxText = const String _checkboxText =
"Checkboxes allow the user to select multiple options from a set."; "Checkboxes allow the user to select multiple options from a set.";
...@@ -26,7 +26,7 @@ const String _switchText = ...@@ -26,7 +26,7 @@ const String _switchText =
const String _switchCode = 'selectioncontrols_switch'; const String _switchCode = 'selectioncontrols_switch';
class SelectionControlsDemo extends StatefulWidget { class SelectionControlsDemo extends StatefulWidget {
static const String routeName = '/selection-controls'; static const String routeName = '/material/selection-controls';
@override @override
_SelectionControlsDemoState createState() => new _SelectionControlsDemoState(); _SelectionControlsDemoState createState() => new _SelectionControlsDemoState();
...@@ -169,15 +169,15 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> { ...@@ -169,15 +169,15 @@ class _SelectionControlsDemoState extends State<SelectionControlsDemo> {
value: switchValue, value: switchValue,
onChanged: (bool value) { onChanged: (bool value) {
setState(() { setState(() {
switchValue = value; switchValue = value;
}); });
} }
), ),
// Disabled switches // Disabled switches
new Switch(value: true, onChanged: null), new Switch(value: true, onChanged: null),
new Switch(value: false, onChanged: null) new Switch(value: false, onChanged: null)
] ],
) ),
); );
} }
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SliderDemo extends StatefulWidget { class SliderDemo extends StatefulWidget {
static const String routeName = '/slider'; static const String routeName = '/material/slider';
@override @override
_SliderDemoState createState() => new _SliderDemoState(); _SliderDemoState createState() => new _SliderDemoState();
......
...@@ -19,7 +19,7 @@ const String _text3 = ...@@ -19,7 +19,7 @@ const String _text3 =
class SnackBarDemo extends StatefulWidget { class SnackBarDemo extends StatefulWidget {
SnackBarDemo({ Key key }) : super(key: key); SnackBarDemo({ Key key }) : super(key: key);
static const String routeName = '/snack-bar'; static const String routeName = '/material/snack-bar';
@override @override
_SnackBarDemoState createState() => new _SnackBarDemoState(); _SnackBarDemoState createState() => new _SnackBarDemoState();
......
...@@ -112,7 +112,7 @@ class _CardDataItem extends StatelessWidget { ...@@ -112,7 +112,7 @@ class _CardDataItem extends StatelessWidget {
} }
class TabsDemo extends StatelessWidget { class TabsDemo extends StatelessWidget {
static const String routeName = '/tabs'; static const String routeName = '/material/tabs';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -33,7 +33,7 @@ final List<_Page> _allPages = <_Page>[ ...@@ -33,7 +33,7 @@ final List<_Page> _allPages = <_Page>[
]; ];
class TabsFabDemo extends StatefulWidget { class TabsFabDemo extends StatefulWidget {
static const String routeName = '/tabs-fab'; static const String routeName = '/material/tabs-fab';
@override @override
_TabsFabDemoState createState() => new _TabsFabDemoState(); _TabsFabDemoState createState() => new _TabsFabDemoState();
......
...@@ -9,7 +9,7 @@ import 'package:flutter/material.dart'; ...@@ -9,7 +9,7 @@ import 'package:flutter/material.dart';
class TextFieldDemo extends StatefulWidget { class TextFieldDemo extends StatefulWidget {
TextFieldDemo({ Key key }) : super(key: key); TextFieldDemo({ Key key }) : super(key: key);
static const String routeName = '/text-field'; static const String routeName = '/material/text-field';
@override @override
TextFieldDemoState createState() => new TextFieldDemoState(); TextFieldDemoState createState() => new TextFieldDemoState();
......
...@@ -11,7 +11,7 @@ const String _introText = ...@@ -11,7 +11,7 @@ const String _introText =
class TooltipDemo extends StatelessWidget { class TooltipDemo extends StatelessWidget {
static const String routeName = '/tooltips'; static const String routeName = '/material/tooltips';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class TwoLevelListDemo extends StatelessWidget { class TwoLevelListDemo extends StatelessWidget {
static const String routeName = '/two-level-list'; static const String routeName = '/material/two-level-list';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
library cupertino; library cupertino;
export 'src/cupertino/activity_indicator.dart'; export 'src/cupertino/activity_indicator.dart';
export 'src/cupertino/button.dart';
export 'src/cupertino/dialog.dart'; export 'src/cupertino/dialog.dart';
export 'src/cupertino/slider.dart'; export 'src/cupertino/slider.dart';
export 'src/cupertino/switch.dart'; export 'src/cupertino/switch.dart';
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
const TextStyle _kButtonTextStyle = const TextStyle(
fontFamily: '.SF UI Text',
inherit: false,
fontSize: 15.0,
fontWeight: FontWeight.normal,
color: CupertinoButton.kBlue,
textBaseline: TextBaseline.alphabetic,
);
final TextStyle _kDisabledButtonTextStyle = _kButtonTextStyle.copyWith(
color: CupertinoButton.kDisabledForeground,
);
final TextStyle _kBackgroundButtonTextStyle = _kButtonTextStyle.copyWith(
color: CupertinoButton.kWhite,
);
const EdgeInsets _kButtonPadding = const EdgeInsets.all(16.0);
const EdgeInsets _kBackgroundButtonPadding =
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 64.0);
/// An iOS style button.
///
/// Takes in a text or an icon that fades out and in on touch. May optionally have a
/// background.
///
/// See also:
///
/// * <https://developer.apple.com/ios/human-interface-guidelines/ui-controls/buttons/>
class CupertinoButton extends StatefulWidget {
// TODO(xster): move this to a common Cupertino color palatte with the next yak.
static const Color kBlue = const Color(0xFF007AFF);
static const Color kWhite = const Color(0xFFFFFFFF);
static const Color kDisabledBackground = const Color(0xFFA9A9A9);
static const Color kDisabledForeground = const Color(0xFFC4C4C4);
CupertinoButton({
@required this.child,
this.padding,
this.color,
@required this.onPressed,
});
/// The widget below this widget in the tree.
///
/// Typically a [Text] widget.
final Widget child;
/// The amount of space to surround the child inside the bounds of the button.
///
/// Defaults to 16.0 pixels.
final EdgeInsets padding;
/// The color of the button's background.
///
/// Defaults to null which produces a button with no background or border.
final Color color;
/// The callback that is called when the button is tapped or otherwise activated.
///
/// If this is set to null, the button will be disabled.
final VoidCallback onPressed;
/// Whether the button is enabled or disabled. Buttons are disabled by default. To
/// enable a button, set its [onPressed] property to a non-null value.
bool get enabled => onPressed != null;
@override
_CupertinoButtonState createState() => new _CupertinoButtonState();
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (!enabled)
description.add('disabled');
}
}
class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProviderStateMixin {
// Eyeballed values. Feel free to tweak.
static const Duration kFadeOutDuration = const Duration(milliseconds: 10);
static const Duration kFadeInDuration = const Duration(milliseconds: 350);
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = new AnimationController(
duration: const Duration(milliseconds: 200),
value: 1.0,
vsync: this,
);
}
@override
void dispose() {
_animationController.dispose();
_animationController = null;
super.dispose();
}
void _handleTapDown(PointerDownEvent event) {
_animationController.animateTo(0.1, duration: kFadeOutDuration);
}
void _handleTapUp(PointerUpEvent event) {
_animationController.animateTo(1.0, duration: kFadeInDuration);
}
void _handleTapCancel(PointerCancelEvent event) {
_animationController.animateTo(1.0, duration: kFadeInDuration);
}
@override
Widget build(BuildContext context) {
final bool enabled = config.enabled;
final Color backgroundColor = config.color;
return new Listener(
onPointerDown: enabled ? _handleTapDown : null,
onPointerUp: enabled ? _handleTapUp : null,
onPointerCancel: enabled ? _handleTapCancel : null,
child: new GestureDetector(
onTap: config.onPressed,
child: new ConstrainedBox(
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
child: new FadeTransition(
opacity: new CurvedAnimation(
parent: _animationController,
curve: Curves.decelerate,
),
child: new DecoratedBox(
decoration: new BoxDecoration(
borderRadius: const BorderRadius.all(const Radius.circular(8.0)),
backgroundColor: backgroundColor != null && !enabled
? CupertinoButton.kDisabledBackground
: backgroundColor,
),
child: new Padding(
padding: config.padding != null
? config.padding
: backgroundColor != null
? _kBackgroundButtonPadding
: _kButtonPadding,
child: new Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: new DefaultTextStyle(
style: backgroundColor != null
? _kBackgroundButtonTextStyle
: enabled
? _kButtonTextStyle
: _kDisabledButtonTextStyle,
child: config.child,
),
),
),
),
),
),
),
);
}
}
...@@ -10,8 +10,8 @@ import 'package:meta/meta.dart'; ...@@ -10,8 +10,8 @@ import 'package:meta/meta.dart';
const TextStyle _kCupertinoDialogTitleStyle = const TextStyle( const TextStyle _kCupertinoDialogTitleStyle = const TextStyle(
fontFamily: '.SF UI Display', fontFamily: '.SF UI Display',
inherit: false, inherit: false,
fontSize: 16.0, fontSize: 17.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.w600,
color: const Color(0xFF000000), color: const Color(0xFF000000),
height: 1.35, height: 1.35,
textBaseline: TextBaseline.alphabetic, textBaseline: TextBaseline.alphabetic,
...@@ -127,7 +127,7 @@ class CupertinoAlertDialog extends StatelessWidget { ...@@ -127,7 +127,7 @@ class CupertinoAlertDialog extends StatelessWidget {
if (title != null) { if (title != null) {
children.add(new Padding( children.add(new Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0), padding: const EdgeInsets.only(left: 20.0, right: 20.0, bottom: 12.0),
child: new DefaultTextStyle( child: new DefaultTextStyle(
style: _kCupertinoDialogTitleStyle, style: _kCupertinoDialogTitleStyle,
textAlign: TextAlign.center, textAlign: TextAlign.center,
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Layout minimum size', (WidgetTester tester) async {
await tester.pumpWidget(
new Center(child: new CupertinoButton(child: new Text(' '), onPressed: null))
);
RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
expect(
buttonBox.size,
greaterThanOrEqualTo(const Size.square(48.0)),
);
expect(
buttonBox.size,
lessThan(const Size.square(100.0)),
);
});
testWidgets('Size grows with text', (WidgetTester tester) async {
await tester.pumpWidget(
new Center(child: new CupertinoButton(child: new Text('blah blah blah'), onPressed: null))
);
RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
expect(
buttonBox.size.width,
greaterThan(48.0),
);
});
testWidgets('Button with background is wider', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new CupertinoButton(
child: new Text(' '),
onPressed: null,
color: new Color(0xFFFFFFFF),
)));
RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
expect(
buttonBox.size.width,
greaterThan(120.0),
);
});
testWidgets('Custom padding', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new CupertinoButton(
child: new Text(' '),
onPressed: null,
padding: new EdgeInsets.all(100.0),
)));
RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
expect(
buttonBox.size,
greaterThan(const Size.square(100.0)),
);
});
testWidgets('Button takes taps', (WidgetTester tester) async {
bool value = false;
await tester.pumpWidget(
new StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return new Center(
child: new CupertinoButton(
child: new Text('Tap me'),
onPressed: () {
setState(() {
value = true;
});
},
),
);
},
),
);
expect(value, isFalse);
// No animating by default.
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
await tester.tap(find.byType(CupertinoButton));
expect(value, isTrue);
// Animates.
expect(SchedulerBinding.instance.transientCallbackCount, equals(1));
});
testWidgets('Disabled button doesn\'t animate', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new CupertinoButton(
child: new Text('Tap me'),
onPressed: null,
)));
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
await tester.tap(find.byType(CupertinoButton));
// Still doesn't animate.
expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment