Flutter本地存储JSON数据:如何通过SharedPreferences独立保存并获取用户项目列表
这个问题很典型——用单个id和content键存储项目确实会和其他SharedPreferences内容混在一起,而且没法支持多个独立项目。咱们换个思路,用单个键存储整个项目列表就能完美解决隔离和多项目的需求,具体实现如下:
核心思路
不再分散存储单个id和content,而是把所有项目打包成一个数组,存储在一个专属的键(比如saved_kits)下。这样既和其他无关键(isLogged、token等)完全隔离,又能轻松管理多个独立项目。
方案1:使用模型类(推荐,更规范)
先定义一个SavedKit模型类来统一项目结构,方便后续操作:
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; class SavedKit { final String id; final String content; // 如果content是JSON字符串,直接存即可;如果是Map,这里可以改成Map<String, dynamic> SavedKit({required this.id, required this.content}); // 转成JSON格式,方便存储 Map<String, dynamic> toJson() { return { 'id': id, 'content': content, }; } // 从JSON解析成对象,方便读取 factory SavedKit.fromJson(Map<String, dynamic> json) { return SavedKit( id: json['id'], content: json['content'], ); } }
保存单个项目
先读取现有列表,添加/更新项目后再存回去:
Future<void> saveKit(SavedKit kit) async { final prefs = await SharedPreferences.getInstance(); // 读取现有项目列表(如果没有则为空数组) final existingKitsJson = prefs.getStringList('saved_kits') ?? []; // 把JSON字符串列表转成SavedKit对象数组 final existingKits = existingKitsJson .map((jsonString) => SavedKit.fromJson(jsonDecode(jsonString))) .toList(); // 可选:移除相同id的项目,避免重复存储 existingKits.removeWhere((existingKit) => existingKit.id == kit.id); // 添加新的项目 existingKits.add(kit); // 把更新后的对象数组转成JSON字符串列表,再存储 final updatedKitsJson = existingKits .map((kit) => jsonEncode(kit.toJson())) .toList(); await prefs.setStringList('saved_kits', updatedKitsJson); }
获取所有项目
直接读取专属键,解析成对象数组:
Future<List<SavedKit>> getSavedKits() async { final prefs = await SharedPreferences.getInstance(); final kitsJson = prefs.getStringList('saved_kits') ?? []; // 把JSON字符串列表转成SavedKit对象数组返回 return kitsJson .map((jsonString) => SavedKit.fromJson(jsonDecode(jsonString))) .toList(); }
方案2:无模型类简化版(快速实现)
如果不想定义模型类,也可以直接用Map来处理:
保存单个项目
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; Future<void> saveKitWithoutModel(String id, String content) async { final prefs = await SharedPreferences.getInstance(); final existingKitsJson = prefs.getStringList('saved_kits') ?? []; // 解析现有项目为Map数组 final existingKits = existingKitsJson.map(jsonDecode).cast<Map<String, dynamic>>().toList(); // 去重(可选) existingKits.removeWhere((kit) => kit['id'] == id); // 添加新项目 existingKits.add({'id': id, 'content': content}); // 转成JSON字符串列表存储 final updatedKitsJson = existingKits.map(jsonEncode).toList(); await prefs.setStringList('saved_kits', updatedKitsJson); }
获取所有项目
Future<List<Map<String, dynamic>>> getSavedKitsWithoutModel() async { final prefs = await SharedPreferences.getInstance(); final kitsJson = prefs.getStringList('saved_kits') ?? []; return kitsJson.map(jsonDecode).cast<Map<String, dynamic>>().toList(); }
额外建议:清理旧数据
因为之前你存储了单个id和content键,建议在首次启动新代码时清理这些冗余数据:
Future<void> cleanOldKitData() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove('id'); await prefs.remove('content'); }
这样操作后,你调用getSavedKits()时只会获取到自己的项目数据,完全不会和其他SharedPreferences键值对混淆,而且能轻松管理多个独立项目。
内容的提问来源于stack exchange,提问作者Lucas Martini
相关产品推荐
相关产品推荐

