Home > Software engineering >  How to use SharedPreferences on switch with changing the theme flutter
How to use SharedPreferences on switch with changing the theme flutter

Time:07-25

I've implemented the theme for the app theme_managers.dart and I've done SharedPreferences on the theme.dart. But the problem is the SharedPreferences on the switch it's working when. I reopen the app it still getting data from last action but the theme(dark mode) get reset all the time when reopen the app.

I don’t understand if I need to put the SharedPreferences on the theme_manager.dart or not. If you know Please point out the problem or some code. Thanks

Please look though my code and you’ll understand the problem.

In theme.dart(some) :

bool colorMode = false;

  @override
  void initState() {
    super.initState();
    getSwitchValues();
  }

  getSwitchValues() async {
    colorMode = await loadbool();
    setState(() {});
  }

  Future<bool> savebool(bool value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    themeManager.toggleTheme(value);
    prefs.setBool("colorMode", value);
    return prefs.setBool("colorMode", value);
  }

  Future<bool> loadbool() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool? colorMode = prefs.getBool("colorMode");

    return colorMode!;
  }
//Switch
               Switch(
                activeColor: Colors.grey,
                value: colorMode,
                onChanged: (bool value) {
                  setState(() {
                    themeManager.toggleTheme(value);
                    colorMode = value;
                    savebool(value);
                  });
                }),

In theme_manager.dart :

class ThemeManager extends ChangeNotifier {

  ThemeMode _themeMode = ThemeMode.light;

  get themeMode => _themeMode;

  toggleTheme(bool isDark){
    _themeMode = isDark? ThemeMode.dark :ThemeMode.light;
    notifyListeners();
  }
}

In main.dart(some) :

ThemeManager themeManager = ThemeManager();

@override
  void initState() {
    themeManager.addListener(themeListener);
    super.initState();
  }

  @override
  void dispose() {
    themeManager.removeListener(themeListener);
    super.dispose();
  }

  themeListener() {
    if (mounted) {
      setState(() {});
    }
  }

MultiProvider(
         Provider(create: (_) => User),
        ChangeNotifierProvider(create: (context) => themeManager)
      ],
      child: MaterialApp(
        title: 'My app',
        themeMode: themeManager.themeMode,
        theme: ThemeData.light(),
        darkTheme: ThemeData.dark(),
        home: const LoginScreen(),
        debugShowCheckedModeBanner: false,
      ),
    );

CodePudding user response:

Try to load the ThemeMode before calling runApp() in your main method, e. g. by adding this to your main method:

void main() async {
  ThemeManager themeManager = ThemeManager();
  await themeManager.loadTheme(); // load the theme before running the app

  runApp(
    MultiProvider(
      providers: [
        Provider(create: (_) => User),
        ChangeNotifierProvider(create: (context) => themeManager),
      ],
      child: MaterialApp(
        title: 'My app',
        themeMode: themeManager.themeMode, // now the theme mode is the one loaded from shared prefs
        theme: ThemeData.light(),
        darkTheme: ThemeData.dark(),
        home: const LoginScreen(),
        debugShowCheckedModeBanner: false,
      ),
    ),
  );
}

And for this to work, add the loadTheme() method to your ThemeManager class:

class ThemeManager extends ChangeNotifier {

  ThemeMode _themeMode = ThemeMode.light;

  get themeMode => _themeMode;

  toggleTheme(bool isDark){
    _themeMode = isDark? ThemeMode.dark :ThemeMode.light;
    notifyListeners();
  }

  Future<void> loadTheme() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isDark = prefs.getBool("colorMode") ?? false;
    _themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
  }
}

CodePudding user response:

Material directly using themeManager.themeMode which returns the ThemeMode.light

 themeMode: themeManager.themeMode,

You might create a method, and make sure to get data from this future before providing on materialApp

class ThemeManager extends ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.light;

  ThemeMode get themeMode => _themeMode;

  Future<void> initTheme() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool? colorMode = prefs.getBool("colorMode");
    // switch if needed
    _themeMode = colorMode == true ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }
  • Related