Flutter中能否使用SharedPreferences存储Map及List类型本地数据?
核心结论
- Flutter 官方提供的
shared_preferences插件不支持直接存储 Map 类型、自定义对象类型的 List,原生仅支持存储int、double、bool、String、List<String>这5种基础类型。 - 你的页面缓存List的需求完全可以实现,通用方案是把结构化数据序列化为JSON字符串后存储,读取时再反序列化为原有结构即可。
具体实现步骤
1. 引入依赖
在 pubspec.yaml 中添加依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 请使用当前最新稳定版
dart:convert 是Dart内置的JSON序列化库,无需额外引入。
2. 给自定义数据类型添加序列化方法
如果你的List元素是基础类型(比如字符串、数字)可以跳过这步;如果是自定义类,需要给类添加 toJson 方法用来转成可序列化的Map,同时添加工厂构造函数从Map还原对象,示例:
class PageItem { final String name; final int id; PageItem({required this.name, required this.id}); Map<String, dynamic> toJson() => { 'name': name, 'id': id, }; factory PageItem.fromJson(Map<String, dynamic> json) => PageItem( name: json['name'] as String, id: json['id'] as int, ); }
3. 页面返回时执行存储逻辑
注意不要在组件的 dispose 生命周期里直接执行异步存储逻辑,容易因为组件销毁导致执行失败。推荐在打开该页面的位置用 await 等待页面返回,再触发存储:
// 跳转进入目标页面的位置 onTap: () async { // 等待目标页面pop返回 final resultList = await Navigator.push( context, MaterialPageRoute(builder: (context) => const TargetPage()), ); // 页面返回后执行存储 if (resultList is List<PageItem>) { final prefs = await SharedPreferences.getInstance(); // 把List转成JSON字符串 final jsonStr = jsonEncode(resultList.map((e) => e.toJson()).toList()); await prefs.setString('target_page_cache_list', jsonStr); } }
如果你的List是List<String>类型,可以直接调用插件自带的 prefs.setStringList('key', yourList) 方法,不需要转JSON。
4. 进入页面时读取缓存
在目标页面的初始化状态逻辑里读取之前存储的缓存即可:
class _TargetPageState extends State<TargetPage> { List<PageItem> _cacheList = []; @override void initState() { super.initState(); _loadCache(); } Future<void> _loadCache() async { final prefs = await SharedPreferences.getInstance(); final cacheStr = prefs.getString('target_page_cache_list'); if (cacheStr != null && cacheStr.isNotEmpty) { final List<dynamic> rawList = jsonDecode(cacheStr); setState(() { _cacheList = rawList.map((e) => PageItem.fromJson(e as Map<String, dynamic>)).toList(); }); } } // 其余页面逻辑 }
注意事项
shared_preferences是轻量键值存储方案,适合存储小体量的配置、短列表缓存,如果你的List长度过千、单条数据体量较大,建议换用Hive、SQLite等专门的本地存储库。- 存储Map类型数据的逻辑和存自定义List完全一致,把Map用
jsonEncode转成String存储,读取时jsonDecode还原即可。
内容的提问来源于stack exchange,提问作者Sanjay
相关产品推荐
相关产品推荐

