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();
}