使用Flutter Riverpod StateProvider切换主题不生效,需重存代码才更新
解决Flutter Riverpod StateProvider切换主题不实时更新问题
问题根源
你的代码存在两个核心问题导致主题无法实时切换:
- 错误的状态监听方式:在
MyApp中你监听的是isDarkThemeProvider.notifier,而非provider本身。notifier的state变化不会触发ConsumerWidget的重建,因此主题不会实时更新。 - 冗余的状态更新逻辑:切换按钮中重复读取
notifier状态,写法冗余且没必要。
修复步骤
1. 修正MyApp的状态监听
将MyApp中获取主题状态的代码替换为直接监听isDarkThemeProvider:
class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // 直接监听provider,状态变化时会触发build重建 final isDarkTheme = ref.watch(isDarkThemeProvider); return GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: ScreenUtilInit( designSize: const Size(360, 690), minTextAdapt: true, splitScreenMode: true, builder: (context, child) { return MaterialApp( builder: FToastBuilder(), debugShowCheckedModeBanner: false, title: 'code', theme: isDarkTheme ? Themes().darkTheme : Themes().lightTheme, onGenerateRoute: onAppGenerateRoute(), routes: appRoutes(), initialRoute: SplashPage.route); }, ), ); } }
2. 简化切换按钮的更新逻辑
切换按钮的onTap可以简化为直接利用update回调的当前状态参数:
onTap: () { ref.read(isDarkThemeProvider.notifier).update((state) => !state); }
或者更直接的写法:
onTap: () { final currentState = ref.read(isDarkThemeProvider); ref.read(isDarkThemeProvider.notifier).state = !currentState; }
为什么这样能解决问题
当你用ref.watch(isDarkThemeProvider)时,Riverpod会在provider的状态变化时自动触发MyApp的build方法重建,从而实时更新MaterialApp的theme属性。之前监听notifier的方式无法感知状态变化,只有热重载时build方法重新执行才会读取最新状态,这就是为什么只有重新保存代码才生效的原因。
内容的提问来源于stack exchange,提问作者SREEVISAKH
相关产品推荐
相关产品推荐

