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

如何将Provider声明的变量像SharedPreferences一样持久化存储?

解决方案:用SharedPreferences实现Provider状态持久化

要让配置修改在重启后保留,需在CountPage中集成SharedPreferences,实现加载持久化数据和修改状态时自动保存的逻辑,具体步骤如下:


1. 重构CountPage类,添加持久化逻辑

SharedPreferences仅支持存储基础数据类型(字符串、数字、布尔值),因此需要将TextAlign和Color转换为可存储格式,再在加载时还原:

  • 添加SharedPreferences实例变量
  • 实现init和loadPreferences方法,启动时加载保存的配置
  • 每个修改状态的方法中,增加保存到SharedPreferences的逻辑

修改后的CountPage代码:

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

class CountPage extends ChangeNotifier {
  late SharedPreferences _prefs;

  int _page = 150;
  int get page => _page;

  bool _visible = false;
  bool get visible => _visible;

  double _font = 40;
  double get font => _font;

  TextAlign align = TextAlign.center;
  Color selection = Colors.red[200]!;

  // 初始化SharedPreferences并加载配置
  Future<void> init() async {
    _prefs = await SharedPreferences.getInstance();
    await loadPreferences();
  }

  // 从SharedPreferences加载数据
  Future<void> loadPreferences() async {
    _page = _prefs.getInt('page') ?? 150;
    _visible = _prefs.getBool('visible') ?? false;
    _font = _prefs.getDouble('font') ?? 40;
    
    // 还原文本对齐方式
    final alignStr = _prefs.getString('align') ?? 'center';
    align = _parseTextAlign(alignStr);
    
    // 还原颜色(Colors.red[200]的十六进制值为FFf8b1b1)
    final colorStr = _prefs.getString('selectionColor') ?? 'FFF8B1B1';
    selection = _parseColor(colorStr);
    
    notifyListeners();
  }

  // TextAlign转字符串存储
  String _textAlignToString(TextAlign align) {
    switch (align) {
      case TextAlign.left: return 'left';
      case TextAlign.right: return 'right';
      default: return 'center';
    }
  }

  // 字符串还原TextAlign
  TextAlign _parseTextAlign(String str) {
    switch (str) {
      case 'left': return TextAlign.left;
      case 'right': return TextAlign.right;
      default: return TextAlign.center;
    }
  }

  // Color转十六进制字符串存储
  String _colorToString(Color color) {
    return color.value.toRadixString(16).padLeft(8, '0').toUpperCase();
  }

  // 十六进制字符串还原Color
  Color _parseColor(String str) {
    return Color(int.parse(str, radix: 16));
  }

  // 保存配置到SharedPreferences
  Future<void> _savePreferences() async {
    await _prefs.setInt('page', _page);
    await _prefs.setBool('visible', _visible);
    await _prefs.setDouble('font', _font);
    await _prefs.setString('align', _textAlignToString(align));
    await _prefs.setString('selectionColor', _colorToString(selection));
  }

  // 修改对齐方式并保存
  change_align_left() {
    align = TextAlign.left;
    _savePreferences();
    notifyListeners();
  }

  change_align_center() {
    align = TextAlign.center;
    _savePreferences();
    notifyListeners();
  }

  change_align_right() {
    align = TextAlign.right;
    _savePreferences();
    notifyListeners();
  }

  // 修改颜色并保存
  change_color_1() {
    selection = Colors.green[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_2() {
    selection = Colors.blue[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_3() {
    selection = Colors.deepOrange[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_4() {
    selection = Colors.pink[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_5() {
    selection = Colors.red[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_6() {
    selection = Colors.brown[200]!;
    _savePreferences();
    notifyListeners();
  }

  change_color_7() {
    selection = Colors.deepPurple[200]!;
    _savePreferences();
    notifyListeners();
  }

  // 修改字体大小并保存
  change_font_1() async {
    _font = 30;
    await _savePreferences();
    notifyListeners();
  }

  change_font_2() async {
    _font = 35;
    await _savePreferences();
    notifyListeners();
  }

  change_font_3() async {
    _font = 40;
    await _savePreferences();
    notifyListeners();
  }

  copy_on() {
    _visible = !_visible;
    _savePreferences();
    notifyListeners();
  }

  page_down() {
    if (_page > 0) {
      _page--;
      _savePreferences();
      notifyListeners();
    }
  }

  page_up() {
    if (_page < 152) {
      _page++;
      _savePreferences();
      notifyListeners();
    }
  }
}

2. 应用启动时初始化CountPage

需在main函数中先加载持久化配置,再将CountPage注入Provider:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final countPage = CountPage();
  await countPage.init(); // 先加载保存的配置

  runApp(
    ChangeNotifierProvider.value(
      value: countPage,
      child: const MyApp(),
    ),
  );
}

3. 修复Option_pageState的代码问题

原代码中initState写在了build方法内部,需移至外部:

class _Option_pageState extends State<Option_page> {
  @override
  void initState() {
    super.initState();
    // 配置已在main中初始化,无需额外操作
  }

  @override
  Widget build(BuildContext context) {
    final countPage = Provider.of<CountPage>(context);

    return Scaffold(
      appBar: AppBar(
        backgroundColor: countPage.selection,
        centerTitle: true,
        title: const Text("설정"),
      ),
      body: Center(
        child: Container(
          child: Column(children: [
            Text(
              "글자 크기 ",
              style: TextStyle(
                fontSize: countPage.font,
              ),
            ),
            Container(
              height: 50,
              child: Row(
                children: [
                  const Container(child: Text('글자크기')),
                  Container(
                    width: 300,
                    color: Colors.green[200],
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        IconButton(
                            onPressed: countPage.change_font_1,
                            icon: const Icon(Icons.looks_one_outlined)),
                        IconButton(
                            onPressed: countPage.change_font_2,
                            icon: const Icon(Icons.looks_two_outlined)),
                        IconButton(
                            onPressed: countPage.change_font_3,
                            icon: const Icon(Icons.looks_3_outlined)),
                      ],
                    ),
                  )
                ],
              ),
            ),
            Container(
              color: countPage.selection,
              height: 50,
              child: Row(
                children: [
                  TextButton(
                    onPressed: () {
                      Navigator.push(context, MaterialPageRoute(builder: (context) => const Color_choic()));
                    },
                    child: const Text("색깔변경                                                  "),
                    style: TextButton.styleFrom(primary: Colors.white),
                  ),
                ],
              ),
            ),
            Container(
              color: Colors.white,
              height: 50,
              child: Row(
                children: [
                  const Text('글자정렬'),
                  Container(
                    width: 300,
                    color: Colors.lightGreen,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        IconButton(
                            onPressed: countPage.change_align_left,
                            icon: const Icon(Icons.format_align_left)),
                        IconButton(
                            onPressed: countPage.change_align_center,
                            icon: const Icon(Icons.format_align_center)),
                        IconButton(
                            onPressed: countPage.change_align_right,
                            icon: const Icon(Icons.format_align_right)),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ]),
        ),
      ),
    );
  }
}

关键说明

  • 数据转换:TextAlign通过字符串标识转换,Color通过十六进制字符串转换,适配SharedPreferences的存储限制
  • 初始化时机:必须在应用启动时先加载持久化数据,确保界面启动时显示保存后的配置
  • 自动保存:每个状态修改方法调用后执行_savePreferences(),保证修改立即持久化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:48:29