Search code examples
flutterdartflutter-provider

Dark Mode Flutter with shared preferences and provider


I want to implement dark/light mode from settings page where a toggle switch is used, everything works good except when I select light mode and restart the app then the app reverts backs to dark mode. What am I doing wrong?

Main.dart

return MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (context) => ThemeProvider()),
  ],
  child: Builder(builder: (BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Unit Converter',
      home: const HomePage(),
      themeMode: themeProvider.themeMode,
      theme: MyThemes.lightTheme,
      darkTheme: MyThemes.darkTheme,
    );
  }),
);

Themeprovider.dart

class ThemeProvider extends ChangeNotifier {
  ThemeMode themeMode = ThemeMode.dark;

  bool get isDarkMode => themeMode == ThemeMode.dark;

  void toggleTheme(bool isOn) {
    themeMode = isOn ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }
}

Setting_page.dart

final themeProvider = Provider.of<ThemeProvider>(context);

SwitchListTile(
title: const Text('Dark Mode'),
                  value: themeProvider.isDarkMode,
                  onChanged: (value) {
                    final provider =
                    Provider.of<ThemeProvider>(context, listen: false);
                    provider.toggleTheme(value);
                  },
                ),

Solution

  • This is because, you haven't stored which theme is selected by user in shared preferences/other database locally. For doing what you're trying to do, you need to keep the theme user has selected currently in shared preferences while changing the theme, and while opening the app, you need to check which theme is selected by the user, and update the theme accordingly. For this:

    Update your ThemeProvider class like this

    class ThemeProvider extends ChangeNotifier {
    
      ///This will get called at initial and check the theme you've currently stored. and update the theme initially.
      ThemeProvider() {
        getThemeAtInit();
      }
    
      
      getThemeAtInit() async{
        SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
        bool? isDarkTheme =
            sharedPreferences.getBool("is_dark");
        if (isDarkTheme != null && isDarkTheme!) {
          themeMode = ThemeMode.dark;
        } else {
          themeMode = ThemeMode.light;
          }
          notifyListeners();
        }
    
      ThemeMode themeMode = ThemeMode.dark;
    
      bool get isDarkMode => themeMode == ThemeMode.dark;
    
      void toggleTheme(bool isOn) async{
            themeMode = isOn ? ThemeMode.dark : ThemeMode.light;
            notifyListeners();
            SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
            sharedPreferences.setBool("is_dark", themeMode == ThemeMode.dark) //Update this as per your condition.
          }
    }
    

    Do this and you're good to go.