ThemeConfig makes it easy to switch the status and navigation bars styles when the platform theme changes.

theme-mode overlay-style custom-overlay-style page-overlay-style

Features

  • Sets system bars' light and dark styles
  • Updates system bars automatically when platform brightness changes
  • Listens to theme mode changes

Getting started

Create a theme profile defining each style independently

final themeProfile = ThemeProfile(
  theme: ThemeData.light(),
  darkTheme: ThemeData.dark(),
  overlayStyle: SystemUiOverlayStyle.light,
  darkOverlayStyle: SystemUiOverlayStyle.dark,
);

Or based on color schemes

final themeProfile = ThemeProfile.fromColorScheme(
  colorScheme: ColorScheme.light(),
  darkColorScheme: ColorScheme.dark(),
  theme: (colorScheme) => ThemeData.from(colorScheme: colorScheme),
  overlayStyle: (colorScheme) => SystemUiOverlayStyle(...),
);

ThemeConfig must be initialized so it can save and load the theme mode preferences

Future<void> main() async {
  ...
  await ThemeConfig.init(themeProfile);
  runApp(MyApp());
}

Wrap the MaterialApp with the ThemeBuilder widget so it can listen to the platform brightness and theme mode changes and change the system bars accordingly

ThemeBuilder(
  builder: (theme) => MaterialApp(
    ...
    theme: theme.light,
    darkTheme: theme.dark,
    themeMode: theme.mode,
  ),
)

Usage

Access the app's brightness and theme mode anywhere in the project

final brightness = ThemeConfig.brightness;
final themeMode = ThemeConfig.themeMode;

Change between theme modes

ThemeConfig.setThemeMode(ThemeMode.light);
ThemeConfig.setThemeMode(ThemeMode.dark);
ThemeConfig.setThemeMode(ThemeMode.system);
  • Example with radio list tile:
Widget myRadioListTile(ThemeMode themeMode) {
  return RadioListTile<ThemeMode>(
    title: Text(themeMode.name),
    value: themeMode,
    groupValue: ThemeConfig.themeMode,
    onChanged: (mode) => setState(() => ThemeConfig.setThemeMode(mode)),
  );
}
Column(children: ThemeMode.values.map(myRadioListTile).toList())

Dynamically redefine the overlay styles

ThemeConfig.setOverlayStyle(newOverlayStyle);
ThemeConfig.setDarkOverlayStyle(newDarkOverlayStyle);

Change the current overlay style

ThemeConfig.setCustomOverlayStyle(customOverlayStyle);

Remove the current overlay style

ThemeConfig.removeCustomOverlayStyle();

Temporarily change the light and/or dark overlay styles when on a specific page

OverlayStyle(
  light: newOverlayStyle,
  dark: newDarkOverlayStyle,
  child: ...
)

Or the custom overlay style

OverlayStyle.custom(
  style: customOverlayStyle,
  child: ...
)

For this widget to work you must also add our observer to the material app

MaterialApp(
  ...
  navigatorObservers: [ThemeConfig.routeObserver],
)

Additional information

If you notice any bugs not present in issues, please file a new issue. If you are willing to fix or enhance things yourself, you are very welcome to make a pull request.