如何使用Provider将List<object>存储到SharedPreferences并在书签页展示
1 前置修正
你的
bookmarkModel类的fromJson方法存在字段拼写错误:json['sutitle']需修改为json['subtitle'],否则解码时会无法正确获取副标题数据。
2 添加依赖
在项目pubspec.yaml中添加shared_preferences依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 可替换为当前最新稳定版
执行flutter pub get完成依赖安装。
3 扩展Provider类增加持久化/读取逻辑
修改你的bookmark类,新增数据存储和加载方法:
import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; // 导入你的bookmarkModel class Bookmark extends ChangeNotifier{ int _count = 0; List<BookmarkModel> bookM = []; void addCount(){ _count++; notifyListeners(); } void addItems(BookmarkModel i){ bookM.add(i); notifyListeners(); // 新增数据后自动触发持久化 saveBookmarks(); } int get count => _count; List<BookmarkModel> get bookMList => bookM; // 持久化书签数据到SharedPreferences Future<void> saveBookmarks() async { final prefs = await SharedPreferences.getInstance(); // 把模型列表转成json字符串列表 List<String> jsonList = bookM.map((item) => jsonEncode(item.toJson())).toList(); await prefs.setStringList('bookmark_list', jsonList); await prefs.setInt('bookmark_count', _count); } // 从SharedPreferences读取书签数据 Future<void> loadBookmarks() async { final prefs = await SharedPreferences.getInstance(); List<String>? jsonList = prefs.getStringList('bookmark_list'); _count = prefs.getInt('bookmark_count') ?? 0; if (jsonList != null) { bookM = jsonList.map((item) => BookmarkModel.fromJson(jsonDecode(item))).toList(); } else { bookM = []; } notifyListeners(); } }
注:类名建议遵循 Dart 规范使用大驼峰命名,这里把bookmark改成Bookmark、bookmarkModel改成BookmarkModel,不符合规范的命名可能会导致潜在问题。
4 调用时机
- 应用初始化时(如main函数初始化完成后、首页initState生命周期中)调用
context.read<Bookmark>().loadBookmarks()加载本地存储的书签数据 - 新增、删除、修改书签数据时,调用
saveBookmarks()方法更新持久化数据
5 书签页展示实现
在书签页面通过Consumer监听数据变化,直接渲染列表即可:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; // 导入你的Provider和模型类 class BookmarkPage extends StatelessWidget { const BookmarkPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('我的书签')), body: Consumer<Bookmark>( builder: (context, bookmarkProvider, child) { if (bookmarkProvider.bookMList.isEmpty) { return const Center(child: Text('暂无书签')); } return ListView.builder( itemCount: bookmarkProvider.bookMList.length, itemBuilder: (context, index) { final item = bookmarkProvider.bookMList[index]; return ListTile( title: Text(item.title ?? '无标题'), subtitle: Text(item.subtitle ?? '无副标题'), trailing: Text('序号:${item.num}'), ); }, ); }, ), ); } }
内容的提问来源于stack exchange,提问作者Muhammad Rasul
相关产品推荐
相关产品推荐

