-
Notifications
You must be signed in to change notification settings - Fork 177
Platform Widget Catalog
Here lies within the list of platform widgets that you can easily use to simplify your Material and Cupertino styles applications...
These are the building blocks that you can use to replace your widgets with to get both Material and Cupertino styled widgets.
A Scaffold that provides the correctly hosted header (AppBar) and navigation bar (Bottom Bar) for each platform. Uses Scaffold for material or CupertinoTabScaffold for cupertino with bottom tabs or CupertinoPageScaffold for cupertino without bottom tabs.
return PlatformScaffold(
appBar: PlatformAppBar()
body: _buildContent(),
bottomNavBar: PlatformNavBar(),
iosContentPadding: false,
iosContentBottomPadding: false
);Note that the use of
iosContentPadding = trueis only required if the content is being obstructed behind the appBar.iosContentBottomPaddingis used if the content needs to be above the navBar and not go behind it. This will not have the translucent effect for iOS when these are set totrue. If that is desirable, then the scrolling and content alignment need to be managed yourself.
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | Scaffold | material: (_, __) => MaterialScaffoldData(...) |
| Cupertino | CupertinoPageScaffold | cupertino: (_, __) => CupertinoPageScaffoldData(...) |
| Cupertino | CupertinoTabScaffold | cupertino: (_, __) => CupertinoPageScaffoldData(...) |
NOTE
If you need to have Scaffold with tabs it is better to use PlatformTabScaffold.
Note: Using
PlatformTabScaffoldprovides a more refined and flexible experience than usingPlatformScaffold.
A Scaffold that provides the correctly hosted header (AppBar) and navigation bar (Bottom Bar) for each platform. Uses Scaffold for material or CupertinoTabScaffold for cupertino with bottom tabs.
return PlatformTabScaffold(
tabController: tabController,
appBarBuilder: (_, index) => PlatformAppBar(),
bodyBuilder: (context, index) => _buildContent(index),
items: _items(context),
);More more detailed example look at:
Note that the use of
iosContentPadding = trueis only required if the content is being obstructed behind the appBar.iosContentBottomPaddingis used if the content needs to be above the navBar and not go behind it. This will not have the translucent effect for iOS when these are set totrue. If that is desirable, then the scrolling and content alignment need to be managed yourself.
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | Scaffold | material: (_, __) => MaterialTabScaffoldData(...) |
| Material | Scaffold | materialTabs: (_, __) => MaterialNavBarData(...) |
| Cupertino | CupertinoPageScaffold | cupertino: (_, __) => CupertinoTabScaffoldData(...) |
| Cupertino | CupertinoTabScaffold | cupertinoTabs: (_, __) => CupertinoTabBarData(...) |
The AppBar is the top Header bar with a title, left-side or right-side buttons. Uses AppBar for material or CupertinoNavigationBar for cupertino.
return PlatformAppBar(
title: new Text('Platform Widgets'),
leading: PlatformIconButton(),
trailingActions: <Widget>[
PlatformIconButton(),
],
);In Cupertino if a solid color header is required and there is a ListView on the page, you would need to add some alpha to the color so that the ListView is not pushed down too far
appBar: PlatformAppBar(
title: Text('iOS Colored Header'),
cupertino: (_, __) => CupertinoNavigationBarData(
// Issue with cupertino where a bar with no transparency
// will push the list down. Adding some alpha value fixes it (in a hacky way)
backgroundColor: Colors.lightGreen.withAlpha(254),
),
),
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | AppBar | material: (_, __) => MaterialAppBarData(...) |
| Cupertino | CupertinoNavigationBar | cupertino: (_, __) => CupertinoNavigationBarData(...) |
The NavBar is placed at the bottom of the page with a set of buttons that typically navigate between screens. Implementing this widget requires the parent widget to manage the currentIndex of the page and to set PlatformNavBar.currrentIndex. Uses BottomAppBar with BottomNavigationBar for material or CupertinoTabBar for cupertino.
return PlatformNavBar(
currentIndex: _selectedTabIndex,
itemChanged: (index) => setState(
() {
_selectedTabIndex = index;
},
),
items: [
BottomNavigationBarItem(),
BottomNavigationBarItem(),
],
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | BottomAppBar | material: (_, __) => MaterialNavBarData(...) |
| Cupertino | CupertinoTabBar | cupertino: (_, __) => CupertinoTabBarData(...) |
The AlertDialog will render a caption/title, body/text and a set of action buttons specific for the platform. Uses AlertDialog for material or CupertinoAlertDialog for cupertino.
Note use
showPlatformDialoginstead of eithershowDialogfrom the Material library orshowCupertinoDialogfrom the Cupertino library.
showPlatformDialog(
context: context,
builder: (_) => PlatformAlertDialog(
title: Text('Alert'),
content: Text('Some content'),
actions: <Widget>[
PlatformDialogAction(),
PlatformDialogAction(),
],
),
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | AlertDialog | material: (_, __) => MaterialAlertDialogData(...) |
| Cupertino | CupertinoAlertDialog | cupertino: (_, __) => CupertinoAlertDialogData(...) |
The DialogAction widget is used to describe the set of buttons on the AlertDialog. Uses TextButton for material or CupertinoDialogAction for cupertino.
PlatformDialogAction(
child: PlatformText('Cancel'),
onPressed: () => Navigator.pop(context),
),Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | TextButton | material: (_, __) => MaterialDialogActionData(...) |
| Cupertino | CupertinoDialogAction | cupertino: (_, __) => CupertinoDialogActionData(...) |
library version >=3.1.0
A platform list tile that renders a ListTile for material or a CupertinoListTile for cupertino.
PlatformListTile(
title: 'title',
onTap: () => Navigator.pop(context),
),A platform button that renders an ElevatedButton or ElevatedButton.icon for material or a CupertinoButton.filled for cupertino.
PlatformElevatedButton(
child: PlatformText('Cancel'),
onPressed: () => Navigator.pop(context),
),Note
The title is a required parameter as that is a required parameter for the CupertinoListTile. You can have different titles between material and cupertino when setting the material or cupertino properties
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | ListTile | material: (_, __) => MaterialListTileData(...) |
| Cupertino | CupertinoListTile | cupertino: (_, __) => CupertinoListTileData(...) |
Note
The icon can only be applied to a the material ElevatedButton when the icon property is set. There is no corresponding icon button for cupertino.
Cupertino to support backward compatibility supports rendering the CupertinoButton when the originalStyle property is set.
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | ElevatedButton | material: (_, __) => MaterialElevatedButtonData(...) |
| Material | ElevatedButton.icon | material: (_, __) => MaterialElevatedButtonData(icon: Icon(Icons...)) |
| Cupertino | CupertinoButton.filled | cupertino: (_, __) => CupertinoElevatedButtonData(...) |
| Cupertino | CupertinoButton | cupertino: (_, __) => CupertinoElevatedButtonData(originalStyle: true) |
A platform button that renders an TextButton or TextButton.icon for material or a CupertinoButton for cupertino.
PlatformElevatedButton(
child: PlatformText('Cancel'),
onPressed: () => Navigator.pop(context),
),Note
The icon can only be applied to a the material ElevatedButton when the icon property is set. There is no corresponding icon button for cupertino.
Cupertino to support backward compatibility supports rendering the CupertinoButton.filled when the originalStyle property is set.
Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | TextButton | material: (_, __) => MaterialTextButtonData(...) |
| Material | TextButton.icon | material: (_, __) => MaterialTextButtonData(icon: Icon(Icons...)) |
| Cupertino | CupertinoButton | cupertino: (_, __) => CupertinoTextButtonData(...) |
| Cupertino | CupertinoButton.filled | cupertino: (_, __) => CupertinoTextButtonData(originalStyle: true) |
A widget that will render uppercase for material. Cupertino will remain unchanged.
return PlatformText('Cancel');A switch widget that will use a Switch for material or a CupertinoSwitch for cupertino.
return PlatformSwitch(
onChanged: (bool value) {},
value: value,
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | Switch | material: (_, __) => MaterialSwitchData(...) |
| Cupertino | CupertinoSwitch | cupertino: (_, __) => CupertinoSwitchData(...) |
A slider widget that will use a Slider for material or a CupertinoSlider for cupertino
return PlatformSlider(
onChanged: (bool value) {},
value: value,
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | Slider | material: (_, __) => MaterialSliderData(...) |
| Cupertino | CupertinoSlider | cupertino: (_, __) => CupertinoSliderData(...) |
A text field widget that will use a TextField for material or a CupertinoTextField for cupertino.
return PlatformTextField();Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | TextField | material: (_, __) => MaterialTextFieldData(...) |
| Cupertino | CupertinoTextField | cupertino: (_, __) => CupertinoTextFieldData(...) |
A text field widget that will use a TextFormField for material or a CupertinoTextFormFieldRow for cupertino.
return PlatformTextFormField();Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | TextFormField | material: (_, __) => MaterialTextFormFieldData(...) |
| Cupertino | CupertinoTextFormFieldRow | cupertino: (_, __) => CupertinoTextFormFieldData(...) |
A clickable (tappable) button with an icon. Uses IconButton for material or CupertinoButton for cupertino.
return PlatformIconButton(
onPressed: () => print('info pressed'),
materialIcon: Icon(Icons.info),
cupertinoIcon: Icon(
CupertinoIcons.info,
size: 28.0,
),
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | IconButton | material: (_, __) => MaterialIconButtonData(...) |
| Cupertino | CupertinoButton | cupertino: (_, __) => CupertinoIconButtonData(...) |
A circular looking progress indicator. Uses CircularProgressIndicator for material or CupertinoActivityIndicator for cupertino.
return PlatformCircularProgressIndicator();Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | CircularProgressIndicator | material: (_, __) => MaterialProgressIndicatorData(...) |
| Cupertino | CupertinoActivityIndicator | cupertino: (_, __) => CupertinoProgressIndicatorData(...) |
The PlatformPopupMenu will render a using a PopupMenuButton for material or use a CupertinoActionSheet for cupertino which will display a list of actions.
return PlatformPopupMenu(
options: [
PopupMenuOption(label: 'One', onTap: _navToPageOne),
PopupMenuOption(label: 'Two', onTap: _navToPageTwo),
PopupMenuOption(label: 'Three', onTap: _navToPageThree)
],
icon: Icon(
context.platformIcon(
material: Icons.more_vert_rounded,
cupertino: CupertinoIcons.ellipsis,
),
),
);Uses:
| Platform | Widget | Extended props add... |
|---|---|---|
| Material | PopupMenuButton | material: (_, __) => MaterialPopupMenuData(...) |
| Cupertino | CupertinoActionSheet | cupertino: (_, __) => CupertinoPopupMenuData(...) |
Display the platform specific modal bottom sheet...
showPlatformModalSheet(
context: context,
builder: (_) => YourSheetContent(),
);Uses:
| Platform | Widget function | Extended props add... |
|---|---|---|
| Material | showModalBottomSheet | material: (_, __) => MaterialModalSheetData(...) |
| Cupertino | showCupertinoModalPopup | cupertino: (_, __) => CupertinoModalSheetData(...) |
Note: Since Material and Cupertino content may be quite different it may be useful to use
PlatformWidget
showPlatformModalSheet(
context: context,
PlatformWidget(
material: (_, __) => _materialPopupContent(),
cupertino: (_, __) => _cupertinoSheetContent(),
),
);Display either the default material date picker or use a slightly opioninated version of a date picker for cupertino which uses a bottom sheet.
showPlatformDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now().subtract(const Duration(days: 1000)),
lastDate: DateTime.now().add(const Duration(days: 1000)),
);Uses:
| Platform | Widget function | Extended props add... |
|---|---|---|
| Material | showDatePicker | material: (_, __) => MaterialDatePickerData(...) |
| Cupertino | (custom) | cupertino: (_, __) => CupertinoDatePickerData(...) |
Note: The Cupertino popup uses a modal bottom sheet with a default cupertino date picker tumbler. If you need to customize the look then set the
cupertinoContentBuilderproperty and return a custom content. If you create your own content builder you will need to manage the state of the date yourself. See the implementation of usingStatefulBuilderorStatefulWidgetto manage state updates within the example project.
final date = await showPlatformDatePicker(
context: context,
firstDate: DateTime.now().subtract(const Duration(days: 100)),
lastDate: DateTime.now().add(const Duration(days: 100)),
initialDate: DateTime.now(),
cupertinoContentBuilder: (contentData, data) =>
_CustomCupertinoDatePicker(contentData: contentData),
);cupertinoContentBuilder is a builder function passing in an instance of DatePickerContentData and optional CupertinoDatePickerData. The returned widget will be a custom designed widget that you return to display within the modal bottom sheet.
You can get the PlatformTarget enum when using platform in order to know what platform is being targeted.
final platform = platform(context);This differs to flutters TargetPlatform in that it includes PlatformTarget.web rather than needing to check for kIsWeb
A widget that will render either the material widget or cupertino widget based on the target platform. The widgets themselves do not need to be specifically Material or Cupertino.
return PlatformWidget(
material: (_, __) => Icon(Icons.flag),
cupertino: (_, __) => Icon(CupertinoIcons.flag),
);Renders a parent widget for either Cupertino or Material while sharing a common child Widget
PlatformWidgetBuilder(
material: (_, child, __) => IniWell(child: child, onTap: _handleTap),
cupertino: (_, child, __) => GestureDetector(child: child, onTap: _handleTap),
child: Container(child: Text('Common text')),
);Render a Material or Cupertino looking icon
Icon(context.platformIcons.book)
//or
Icon(PlatformIcons(context).book)View the source or screenshots for the list of icons.
Helper function to a Material or Cupertino theme data property based on the platform
Text(
platform.text,
textAlign: TextAlign.center,
style: platformThemeData(
context,
material: (ThemeData data) => data.textTheme.headline5,
cupertino: (CupertinoThemeData data) => data.textTheme.navTitleTextStyle,
),
)