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

如何为基于Provider的Flutter应用添加持久化存储逻辑?

为Provider状态添加自定义对象列表的持久化实现方案

步骤1:添加持久化依赖

在pubspec.yaml中添加shared_preferences依赖,用于存储序列化后的JSON数据:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5
  shared_preferences: ^2.2.2

执行flutter pub get完成依赖安装。

步骤2:让自定义类支持序列化

修改MyData类,添加JSON转换方法,处理DateTime的字符串转换(因为SharedPreferences无法直接存储DateTime类型):

class MyData {
  final DateTime time;
  final int value;
  MyData(this.time, this.value);

  // 转换为JSON格式
  Map<String, dynamic> toJson() {
    return {
      'time': time.toIso8601String(),
      'value': value,
    };
  }

  // 从JSON解析为MyData对象
  factory MyData.fromJson(Map<String, dynamic> json) {
    return MyData(
      DateTime.parse(json['time']),
      json['value'],
    );
  }
}

步骤3:修改状态类,加入持久化逻辑

将原State类重命名为DataState(避免与Flutter内置State冲突),添加加载/保存数据的异步方法,并在数据变更后自动触发保存:

import 'package:shared_preferences/shared_preferences.dart';

class DataState with ChangeNotifier {
  late List<MyData> _dataset = [];
  List<MyData> get dataset => _dataset;

  DataState() {
    // 初始化时加载本地存储的数据
    _loadData();
  }

  // 从本地加载数据
  Future<void> _loadData() async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = prefs.getString('dataset');
    if (jsonString != null) {
      final List<dynamic> jsonList = jsonDecode(jsonString) as List;
      _dataset = jsonList.map((json) => MyData.fromJson(json)).toList();
      notifyListeners();
    }
  }

  // 将数据保存到本地
  Future<void> _saveData() async {
    final prefs = await SharedPreferences.getInstance();
    final List<Map<String, dynamic>> jsonList = _dataset.map((data) => data.toJson()).toList();
    await prefs.setString('dataset', jsonEncode(jsonList));
  }

  void addData(DateTime time, int value) {
    MyData datapoint = MyData(time, value);
    _dataset.add(datapoint);
    notifyListeners();
    _saveData();
  }

  void clearData() {
    _dataset = [];
    notifyListeners();
    _saveData();
  }
}

步骤4:更新Provider注册与UI调用

  1. 修改main函数中的Provider注册:
void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => DataState()),
      ],
      child: const MyApp(),
    ),
  );
}
  1. 更新UI中对状态类的引用:
// MyHomePage中的按钮点击事件
IconButton(
    onPressed: () => context.read<DataState>().addData(DateTime.now(), 100),
    icon: const Icon(Icons.add)),
IconButton(
    onPressed: () => context.read<DataState>().clearData(),
    icon: const Icon(Icons.remove))
// Count组件中的状态监听
'${context.watch<DataState>().dataset.length}',

注意事项

  • SharedPreferences适合存储轻量数据,若数据集较大,建议改用Hive或sqflite等本地数据库方案
  • 确保所有数据变更操作后都调用_saveData,避免数据丢失
  • 采用ISO8601格式存储DateTime,保证跨平台解析的兼容性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:55:22