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

Flutter中Switch+SharedPreferences切换主题重启失效问题排查

问题核心

你的问题出在ThemeManager初始化时没有读取SharedPreferences中保存的主题状态,每次重启App它都会默认回到ThemeMode.light,而Switch的状态是从SharedPreferences加载的,所以出现Switch状态保留但主题重置的矛盾。

正确的做法是把SharedPreferences的逻辑整合到ThemeManager中,让主题管理器自身负责状态的持久化与读取,这样UI层只需要和ThemeManager交互即可。

修改方案

1. 重构theme_manager.dart

让ThemeManager完全接管主题的加载、切换与持久化:

import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';

class ThemeManager extends ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.light;
  static const String _themeKey = "colorMode";

  ThemeMode get themeMode => _themeMode;

  // 构造时自动加载保存的主题
  ThemeManager() {
    _loadSavedTheme();
  }

  Future<void> _loadSavedTheme() async {
    final prefs = await SharedPreferences.getInstance();
    // 默认值设为false(浅色主题)
    bool isDark = prefs.getBool(_themeKey) ?? false;
    _themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }

  Future<void> toggleTheme(bool isDark) async {
    _themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
    // 保存状态到SharedPreferences
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_themeKey, isDark);
    notifyListeners();
  }
}

2. 简化theme.dart中的代码

移除本地的SharedPreferences相关逻辑,直接通过Provider与ThemeManager交互:

// 不需要再定义本地colorMode变量,直接从ThemeManager获取状态
bool get colorMode => Provider.of<ThemeManager>(context).themeMode == ThemeMode.dark;

@override
Widget build(BuildContext context) {
  return Switch(
    activeColor: Colors.grey,
    value: colorMode,
    onChanged: (bool value) {
      // 调用ThemeManager的切换方法
      Provider.of<ThemeManager>(context, listen: false).toggleTheme(value);
    },
  );
}

// 移除原来的initState、getSwitchValues、savebool、loadbool方法

3. 调整main.dart的主题引用

确保MaterialApp使用你在theme_constant.dart中定义的自定义主题:

ThemeManager themeManager = ThemeManager();

// ... 其他代码不变
MultiProvider(
  providers: [
    Provider(create: (_) => User),
    ChangeNotifierProvider(create: (context) => themeManager)
  ],
  child: MaterialApp(
    title: 'My app',
    themeMode: themeManager.themeMode,
    theme: lightTheme, // 引用theme_constant中的浅色主题
    darkTheme: darkTheme, // 引用theme_constant中的深色主题
    home: const LoginScreen(),
    debugShowCheckedModeBanner: false,
  ),
);

补充说明

theme_constant.dart中的主题定义没有问题,只要在MaterialApp中正确引用即可生效。重构后,ThemeManager完全接管主题状态的管理与持久化,避免了状态分散导致的不同步问题。

内容的提问来源于stack exchange,提问作者It'sPhil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:57:35