-
Notifications
You must be signed in to change notification settings - Fork 174
Home
pub.dev: https://pub.dev/packages/flutter_platform_widgets/install
Instead of having to write conditional code like this...
if (Platform.isAndroid) {
return ElevatedButton(onPressed: onPressed, child: child);
} else if (Platform.isIOS) {
return CupertinoButton.filled(onPressed: onPressed, child: child);
}
you can use a single platform
widget which will render the correct underlying widget based on the ThemeData.platform
property...
return PlatformElevatedButton(onPressed: onPressed, child: child);
The heavy lifting of choosing the right widget is done for you.
You can also specify what design language you want for any supported platforms within flutter. These include:
- Android
- iOS
- Web
- Macos
- Windows
- Linux
To make the most out of a single PlatformWidget
it is best to replace the MaterialApp
with the PlatformApp
and to add the PlatformProvider
widget above it. Although strictly both are not required, some platform specific widgets may expect them to be present. from v3.3 onwards a PlatformTheme
widget can be added between PlatformProvider
and PlatformApp
to control the light and dark themes of both the material and cupertino style independently of each other.
Replace the MaterialApp
with the following...
PlatformProvider(
builder: (context) =>
PlatformTheme(
builder: (context) => PlatformApp(
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
),
),
)
Note: setting localizationsDelegates
property is recommended since localizations are not by default used within Cupertino, particularly if you mix and match material and cupertino widgets within your application.
Properties on PlatformProvider
widget include...
Property | Description |
---|---|
initialPlatform | A platform override value from TargetPlatform or null to default to the device's platform |
settings | An instance of type PlatformSettingsData which can control what platform gets what design language widgets |
builder (required) | The main builder function which typically has the PlatformApp or PlatformTheme as its child |
Notable properties on the PlatformApp
widget include...
Property | Description |
---|---|
PlatformApp.router | Named constructor which configures the underlying MaterialAp.router or CupertinoApp.router widgets |
There are a number of settings that you can set that applies to the entire application when you add PlatformProvider
above the main PlatformApp
widget. To have additional settings, just add it to settings
of the provider.
PlatformProvider(
settings: PlatformSettingsData(...),
builder: ...
)
iosUsesMaterialWidgets
If you plan to use a mixture of Material
and Cupertino
widgets within your app and use PlatformApp
for iOS then you need to set the following
This is because material
widgets expect a Scaffold
or Material
parent widget which by default is not added when using the cupertino
widgets.
platformStyle
By default the style of an android application will take the material
style, and an apple application will take the cupertino
style. You can change what style the target platform will have by setting the platformStyle
property.
The following are the defaults used.
Platform | Style |
---|---|
android | Material |
windows | Material |
web | Material |
fushia | Material |
linux | Material |
ios | Cupertino |
macos | Cupertino |
iosUseZeroPaddingForAppbarPlatformIcon
From v2.1 you can ensure that for a PlatformIconButton
added to the cupertino app bar have zero padding which is required to visually align properly on the app bar. This zero padding is ignored if the PlatformIconButton
already has a padding added to it.
legacyIosUsesMaterialWidgets
Not recommended to set, however exists for older projects that want to ensure a Material
as a parent. Prefer setting iosUsesMaterialWidgets
wrapCupertinoAppBarMiddleWithMediaQuery
package version >=3.2.0
Controls whether the CupertinoNavigationBar
middle property is wrapped with a MediaQuery as defined in this flutter issue: https://github.com/flutter/flutter/issues/42759#issuecomment-591087271. This has a default value of true
which will change the behaviour of the from version 3.1.0 of the package. If the behaviour is not required then set this property to false
Each platform widget has the list of properties shared between material
and cupertino
within the platform constructor itself, in the same way the default flutter widgets are made. However not all properties are common between the two. So in this case you can further customise the platform widget specifically for the target platform.
Take the PlatformTextButton
widget as an example:
return PlatformElevatedButton(
onPressed: onPressed,
child: const Text('Click Me!'),
);
Here the onPressed
and child
properties are common between material
and cupertino
so they are provided directly on the PlatformTextButton
constructor. However what is being used for material
is the TextButton
widget and for cupertino
it is the CupertinoButton
widget. If you want to change or handle something specific for the target platform widget you need to extend it by doing this...
return PlatformElevatedButton(
onPressed: onPressed,
child: const Text('Click Me!'),
material: (_, __) => MaterialTextButtonData(
autofocus: true,
),
cupertino: (_, __) => CupertinoTextButtonData(
disabledColor: Colors.white
),
);
The (_, __)
builder arguments are BuildContext
and PlatformTarget
which you can use explicitly if you need to use the context or need to know about the platform that is being targeted.
To get the full list of possible extended properties for each platform widget it is best to look at the source code itself as the amount of properties some of the widgets have is just too much to list.