-
Notifications
You must be signed in to change notification settings - Fork 177
Theming
From v3.3 onwards you can set the theme of both the material and cupertino themes more succinctly by using the PlatformTheme
widget.
package version >=3.3.0
For versions 3.3 and above you can change the app setup to the following. You no longer need to set the theme for the PlatformApp
material and cupertino data fields.
final currentTheme = ThemeData.light(); // Change theme for your needs
PlatformProvider(
builder: (context) => PlatformTheme(
materialLightTheme: currentTheme,
builder: (context) =>
PlatformApp(
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
),
),
)
With `PlatformTheme` you can set the light and dark theme of both material and cupertino, but also set the `ThemeMode` for the application
```dart
PlatformTheme(
themeMode: themeMode,
materialLightTheme: materialLightTheme,
materialDarkTheme: materialDarkTheme,
cupertinoLightTheme: cupertinoLightTheme,
cupertinoDarkTheme: cupertinoDarkTheme,
builder: (context) => PlatformApp(...)
)
See below for how to create material and cupertino light and dark themes.
Properties on the PlatformTheme
widget include:
Property | Description |
---|---|
themeMode | ThemeMode value of either light , dark or system
|
materialLightTheme | The light theme for material |
materialDarkTheme | The dark theme for material |
cupertinoLightTheme | The light theme for cupertino |
cupertinoDarkTheme | The dark theme for cupertino |
matchCupertinoSystemChromeBrightness | Sets the SystemChrome brightness for cupertino based off the ThemeMode. Defaults to true |
onThemeModeChanged | When the ThemeMode changes via the PlatformTheme.of(context).themeMode property |
builder (required) | The main builder function which typically has the PlatformApp as its child |
If you want the app to change from light
to dark
themes you can use the PlatformTheme.of(context).themeMode
property from anywhere in your application.
PlatformElevatedButton(
onPressed: () => PlatformTheme.of(context).themeMode = ThemeMode.dark,
child: Text('Change to dark mode'),
)
If you need to store the currently set theme you can use the onThemeModeChanged
callback. Saving externally to the application is not the responsibility of this library.
PlatformTheme(
themeMode: initialThemeMode,
onThemeModeChanged: (themeMode) { /* Store the changed theme mode here */ }
)
The simpliest way to get a cupertino theme in your app is to copy the values from the material theme and apply it to the PlatformApp
.
final materialTheme = ThemeData.light();
final cupertinoTheme = MaterialBasedCupertinoThemeData(materialTheme: materialTheme);
PlatformProvider(
builder: (context) => PlatformTheme(
materialLightTheme: materialTheme,
cupertinoLightTheme: cupertinoTheme,
builder: (context) => PlatformApp(
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
),
),
)
If you support dark mode, either via using the devices default system mode or having the user change the theme within your app you will need to ensure the theme data used is correct.
// Your default app's theme mode selection which can be changed.
const themeMode = ThemeMode.light;
final lightTheme = ThemeData.light();
final darkTheme = ThemeData.dark();
PlatformProvider(
builder: (context) => PlatformTheme(
themeMode: lightTheme,
materialLightTheme: lightTheme,
materialDarkTheme: darkTheme,
builder: (context) => PlatformApp(
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
),
),
)
Using dark mode for cupertino is not as straight forward due to a number of issues raised with flutter. See #71590, #80860, #48438, #51899
These can be mitigated by having the cupertino theme customised...
final darkTheme = ThemeData.dark();
const darkDefaultCupertinoTheme = CupertinoThemeData(brightness: Brightness.dark);
final cupertinoDarkTheme = MaterialBasedCupertinoThemeData(
materialTheme: darkTheme.copyWith(
cupertinoOverrideTheme: CupertinoThemeData(
brightness: Brightness.dark,
barBackgroundColor:
darkDefaultCupertinoTheme.barBackgroundColor,
textTheme: CupertinoTextThemeData(
navActionTextStyle: darkDefaultCupertinoTheme
.textTheme.navActionTextStyle
.copyWith(color: const Color(0xF0F9F9F9)),
navLargeTitleTextStyle: darkDefaultCupertinoTheme
.textTheme.navLargeTitleTextStyle
.copyWith(color: const Color(0xF0F9F9F9)),
),
),
),
);
Then just set the cupertino themes on the PlatformTheme
. Ideally match the system chrome to match dark mode also.
PlatformProvider(
builder: (context) => PlatformTheme(
cupertinoDarkTheme: cupertinoDarkTheme,
PlatformApp(
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
),
),
),
In cases where your app can switch between material and cupertino themes (much like the example from this project) you need to make sure the correct theme is kept the same.
Somewhere in your app you can just change the target platform...
// Perhaps this in a button click handler
final provider = PlatformProvider.of(context)!;
isMaterial(context)
? provider.changeToCupertinoPlatform()
: provider.changeToMaterialPlatform();
This will rebuild the app with the new target platform however you need to make sure the correct theme is applied. Coupled with light and dark theme the complete theme setup probably should be this...
// Your default app's theme mode selection which can be changed.
const themeMode = ThemeMode.light;
final materialLightTheme = ThemeData.light();
final materialDarkTheme = ThemeData.dark();
final cupertinoLightTheme = MaterialBasedCupertinoThemeData(materialTheme: materialLightTheme);
const darkDefaultCupertinoTheme = CupertinoThemeData(brightness: Brightness.dark);
final cupertinoDarkTheme = MaterialBasedCupertinoThemeData(
materialTheme: materialDarkTheme.copyWith(
cupertinoOverrideTheme: CupertinoThemeData(
brightness: Brightness.dark,
barBackgroundColor:
darkDefaultCupertinoTheme.barBackgroundColor,
textTheme: CupertinoTextThemeData(
navActionTextStyle: darkDefaultCupertinoTheme
.textTheme.navActionTextStyle
.copyWith(color: darkTheme.primaryColor),
navLargeTitleTextStyle: darkDefaultCupertinoTheme
.textTheme.navLargeTitleTextStyle
.copyWith(color: const Color(0xF0F9F9F9)),
),
),
),
);
PlatformProvider(
builder: (context) => PlatformTheme(
themeMode: themeMode,
materialLightTheme: materialLightTheme,
materialDarkTheme: materialDarkTheme,
cupertinoLightTheme: cupertinoLightTheme,
cupertinoDarkTheme: cupertinoDarkTheme,
builder: (context) =>
PlatformApp(
title: 'Flutter Platform Widgets',
home: _YourHomePage_(),
);
),
)