-
Notifications
You must be signed in to change notification settings - Fork 176
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 = true
is only required if the content is being obstructed behind the appBar.iosContentBottomPadding
is 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
PlatformTabScaffold
provides 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 = true
is only required if the content is being obstructed behind the appBar.iosContentBottomPadding
is 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
showPlatformDialog
instead of eithershowDialog
from the Material library orshowCupertinoDialog
from 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
cupertinoContentBuilder
property 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 usingStatefulBuilder
orStatefulWidget
to 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,
),
)