Package selection guidance compiled from public package information, community data, and project usage.
Adaptive Theme is a Flutter package that enables dynamic switching between light and dark themes, with built-in support for system-level theme adaptation. It simplifies theme management by allowing developers to seamlessly respond to user preferences across devices. The package integrates smoothly with Flutter’s theme system and supports all major platforms including Android, iOS, Web, macOS, Windows, and Linux. It provides a clean API for programmatically changing themes or syncing with the device's system settings.
Use cases
Dynamic theme switching in apps
Implementing system theme awareness
Creating accessible UIs with dark mode
Supporting user preference persistence
Building cross-platform applications
Enabling real-time theme updates
Key features
System theme auto-detection
Runtime theme switching
Persistent theme storage
Cross-platform compatibility
Simple API integration
Theme customization options
Suitable for
Developers building responsive UIs
Apps requiring dark mode support
Projects targeting multiple platforms
User-centric design implementations
Teams prioritizing accessibility
Flutter beginners learning theming
Considerations
Requires manual handling of theme state persistence
Limited to light/dark theme toggling
May need additional logic for complex theme schemes
Depends on correct initialization order
Not suitable for multi-theme designs beyond light/dark
Needs careful handling in multi-page navigation
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
Adaptive Theme
The easiest way to add support for light and dark themes in your Flutter app. It allows you
to manually set a light or dark theme and also lets you define themes based on the system. It also
persists the theme mode changes across app restarts.
Now that you have initialized your app as mentioned above. It's very easy and straightforward to
change your theme modes: light to dark, dark to light, or to system default.
// sets theme mode to darkAdaptiveTheme.of(context).setDark();
// sets theme mode to lightAdaptiveTheme.of(context).setLight();
// sets theme mode to system defaultAdaptiveTheme.of(context).setSystem();
Toggle Theme Mode
AdaptiveTheme allows you to toggle between light, dark, and system themes the easiest way possible.
AdaptiveTheme.of(context).toggleThemeMode();
Changing Themes
If you want to change the theme entirely, e.g., change all the colors to some other color swatch,
then you can use setTheme method.
AdaptiveTheme is smart enough to keep your default themes handy that you provided at the time
of initialization. You can fall back to those default themes in a very easy way.
AdaptiveTheme.of(context).reset();
This will reset your theme as well as theme mode to the initial values provided at the time of
initialization.
Set Default Theme
AdaptiveTheme persists theme mode changes across app restarts and uses the default themes to set
theme modes (light/dark) on. You can change this behavior if you want to set a different theme as
the default theme other than the one provided at the time of initialization.
This comes in handy when you're fetching themes remotely on app starts and the setting theme as the
current theme.
Doing so is quite easy. You would set a new theme normally as you do by calling setTheme method
but this time, with a flag isDefault set to true.
This is only useful when you might want to reset to default theme at some point.
When you change your theme, the next app run won't be able to pick the most recent theme directly
before rendering with the default theme for the first time. This is because at the time of
initialization, we cannot run async code to get the previous theme mode. However, it can be avoided
if you make your main() method async and load the previous theme mode asynchronously. The example
below shows how it can be done.
Notice that I passed the retrieved theme mode to my material app so that I can use it while
initializing the default theme. This helps to avoid theme change flickering on app startup.
Listen to the theme mode changes
You can listen to the changes in the theme mode via a ValueNotifier. This can be useful when
designing a theme settings screen or developing UI to show theme status.
AdaptiveTheme.of(context).modeChangeNotifier.addListener(() {
// do your thing.
});
Starting from v3.3.0, you can now set debugShowFloatingThemeButton to true and enable a
floating button that can be used to toggle theme mode very easily. This is useful when you want to
test your app with both light and dark themes without restarting the app or navigating to the
settings screen where your theme settings are available.
This is only useful in scenarios where you load your themes dynamically from network in the splash screen or some initial screens of the app. Please note that AdaptiveTheme does not persist the themes, it only persists the theme modes(light/dark/system). Any changes made to the provided themes won't be persisted and you will have to do the same changes at the time of the initialization if you want them to apply every time app is opened. e.g changing the accent color.
Using SharedPreferences
This package uses shared_preferences plugin internally to persist theme mode changes. If your app uses shared_preferences which might be the case all the time, clearing your shared_preferences at the time of logging out or signing out might clear these preferences too. Be careful not to clear these preferences if you want it to be persisted.
/// Do not remove this key from preferencesAdaptiveTheme.prefKey
You can use the above key to exclude it while clearing all the preferences.
Or you can call AdaptiveTheme.persist() method after clearing the preferences to make it persistable
again as shown below.
final prefs = awaitSharedPreferences.getInstance();
await prefs.clear();
AdaptiveTheme.persist();
Using CupertinoTheme
Wrap your CupertinoApp with CupertinoAdaptiveTheme in order to apply themes.