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

Flutter主题偏好无法保存重启不生效问题求助

Flutter主题偏好无法保存重启失效问题修复

我正在为Flutter计算器应用添加深色/浅色/自定义主题模式,参考了相关教程,但主题偏好无法保存,重启应用后不会生效。项目使用shared_preferences库,代码为个人计算器项目代码。

当前相关代码

StorageManager 代码

import 'package:shared_preferences/shared_preferences.dart';
import 'package:calculator/main.dart';
import 'package:calculator/theme_manager.dart';
import 'package:calculator/settings.dart';

class StorageManager {
  static void saveData(String key, dynamic value) async {
    final prefs = await SharedPreferences.getInstance();
    print(value);
    if (value is int) {
      prefs.setInt(key, value);
    } else if (value is String) {
      prefs.setString(key, value);
    } else if (value is bool) {
      prefs.setBool(key, value);
    } else {
      print("Invalid Type");
    }
  }

  static Future<dynamic> readData(String key) async {
    final prefs = await SharedPreferences.getInstance();
    dynamic obj = prefs.get(key);
    return obj;
  }

  static Future<bool> deleteData(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.remove(key);
  }
}

ThemeManager 初始化代码

late ThemeData _themeData;
var _buttonsData;

ThemeData getTheme() => _themeData;
getButtons() => _buttonsData;

ThemeNotifier() {
  StorageManager.readData('themeMode').then((value) {
    var themeMode = value ?? 'light';
    if (themeMode == 'light') {
        _themeData = lightTheme;
    } else if (themeMode == 'dark') {
        _themeData = darkTheme;
    } else {
        _themeData = customTheme;
    }
      notifyListeners();
    });
  StorageManager.readData('buttonsMode').then((value) {
    var buttonsMode = value ?? 'circle';
    if (buttonsMode == 'circle') {
        _buttonsData = circledButtons;
    } else if (buttonsMode == 'rounded') {
        _buttonsData = roundedButtons;
    } else if (buttonsMode == 'box') {
        _buttonsData = boxButtons;
    }
      notifyListeners();
  });
}

原示例中ThemeData _themeData;前没有late修饰符,但去掉它我的代码就无法运行,这会不会是问题所在?


问题排查与修复方案

1. late修饰符的影响

late是延迟初始化关键字,本身不会导致存储失效。你的代码中因为_themeData是在异步回调中赋值的,必须用late来避免未初始化报错,所以这不是导致主题不持久的直接原因。

2. 存储逻辑的核心问题

(1)保存方法未等待异步操作完成

当前saveData方法是void返回值,异步存储操作可能还没完成,应用就已经退出,导致数据未写入。修改为返回Future<void>并等待存储操作完成:

static Future<void> saveData(String key, dynamic value) async {
  final prefs = await SharedPreferences.getInstance();
  print(value);
  if (value is int) {
    await prefs.setInt(key, value);
  } else if (value is String) {
    await prefs.setString(key, value);
  } else if (value is bool) {
    await prefs.setBool(key, value);
  } else {
    print("Invalid Type");
  }
}

调用保存方法时必须使用await,确保数据写入完成:

await StorageManager.saveData('themeMode', 'dark');

(2)确认切换主题时是否调用了保存方法

检查主题切换的逻辑,比如用户选择深色主题后,是否执行了saveData方法。如果没有调用,自然不会将主题偏好持久化到本地。

(3)初始化时的异步时序问题

ThemeNotifier构造函数中通过异步读取存储来赋值,可能在UI渲染时_themeData还未被赋值,导致初始主题显示异常。可以在ThemeNotifier中先设置默认主题,再在异步回调中更新:

late ThemeData _themeData = lightTheme; // 先设置默认值
var _buttonsData = circledButtons;

// 构造函数逻辑不变

3. 其他验证点

  • 检查themeMode键名在保存和读取时是否完全一致,避免拼写错误。
  • 在saveData后立即调用readData打印返回值,验证SharedPreferences是否能正常读写数据。
  • 确认ThemeNotifier正确继承了ChangeNotifier,notifyListeners()在主题赋值后正确调用,确保UI能收到主题更新通知。

内容的提问来源于stack exchange,提问作者user15066075

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:48:19