You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:11:08