Flutter明暗模式切换后Provider未触发主题即时更新问题
问题解决:Flutter主题切换后不生效,仅重启应用生效
核心原因
你的MaterialApp没有监听ThemeProvider的状态变化。当前代码中使用Provider.of<ThemeProvider>(context, listen: false)获取实例,listen: false意味着不会监听状态更新,所以调用toggleTheme后虽然systemThemeMode已修改,但MaterialApp不会重新构建,自然不会应用新的主题模式。
解决方案
通过Consumer组件包裹MaterialApp,或者将Provider.of的listen参数设为true,让MaterialApp能响应ThemeProvider的状态变化。
方法1:使用Consumer(推荐)
Consumer可以精准监听指定Provider的变化,仅在需要更新的部分重建,性能更优:
修改main.dart中的builder部分:
return MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => UserController()), ChangeNotifierProvider(create: (context) => TeamsController()), ChangeNotifierProvider(create: (context) => MatchListController()), ChangeNotifierProvider(create: (context) => NewsProvider()), ChangeNotifierProvider(create: (context) => ThemeProvider()), ], builder: (context, _) { return Consumer<ThemeProvider>( builder: (context, themeProvider, child) { return MaterialApp( debugShowCheckedModeBanner: false, theme: LightDarkTheme.lightTheme, darkTheme: LightDarkTheme.darkTheme, title: 'CricketR Plus', themeMode: themeProvider.systemThemeMode, home: LoginScreen(), ); }, ); });
方法2:修改Provider.of的listen参数
将listen: false改为默认的listen: true(可省略该参数,默认值为true):
return MultiProvider( providers: [ // 其他Provider保持不变 ChangeNotifierProvider(create: (context) => ThemeProvider()), ], builder: (context, _) { final themeProvider = Provider.of<ThemeProvider>(context); return MaterialApp( debugShowCheckedModeBanner: false, theme: LightDarkTheme.lightTheme, darkTheme: LightDarkTheme.darkTheme, title: 'CricketR Plus', themeMode: themeProvider.systemThemeMode, home: LoginScreen(), ); });
额外优化建议
你的ThemeProvider中isDarkMode的初始化逻辑和systemThemeMode可能存在不一致:
systemThemeMode从本地存储preferences读取isDarkMode直接取系统当前亮度
可以统一初始化逻辑,避免冲突:
class ThemeProvider extends ChangeNotifier { ThemeMode systemThemeMode; bool isDarkMode; ThemeProvider() { // 从本地存储读取主题设置 final savedDarkMode = preferences.getBool(Keys.isDarkMode); if (savedDarkMode == null) { // 未设置过,取系统亮度 isDarkMode = SchedulerBinding.instance.window.platformBrightness == Brightness.dark; } else { isDarkMode = savedDarkMode; } systemThemeMode = isDarkMode ? ThemeMode.dark : ThemeMode.light; } toggleTheme(bool isPro) { if (isPro) { isDarkMode = !isDarkMode; preferences.setBool(Keys.isDarkMode, isDarkMode); systemThemeMode = isDarkMode ? ThemeMode.dark : ThemeMode.light; notifyListeners(); } } }
内容的提问来源于stack exchange,提问作者rameez khan
相关产品推荐
相关产品推荐

