Flutter中如何将对象列表的布尔收藏状态存储到Shared Preferences
前置准备
首先在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 可替换为最新稳定版
步骤1:修复原有模型类问题
原有ZekrModel的toggleDone方法声明了布尔返回值但无返回,同时screenWidget属于UI组件不需要参与持久化,我们使用全局唯一的zekrTitle作为收藏状态的存储key,修正后代码:
class ZekrModel { final String zekrTitle; final String zekrImage; final String zekrCat; final Widget screenWidget; bool isFav; ZekrModel({ required this.zekrTitle, required this.zekrImage, required this.zekrCat, required this.screenWidget, this.isFav = false, // 默认未收藏 }); // 切换收藏状态,返回最新状态 bool toggleDone() { isFav = !isFav; return isFav; } }
步骤2:改造Provider类实现持久化逻辑
在Provider中新增SharedPreferences初始化、本地状态读取、状态更新后写入本地的逻辑:
import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter/foundation.dart'; class ZekrProvider with ChangeNotifier{ late SharedPreferences _prefs; List<ZekrModel> _zekrList = [ ZekrModel( zekrTitle: 'أذكار المساء', zekrImage: 'assets/images/sunset.png', zekrCat: 'Azkar', screenWidget: AlmasaaScreen(), ), ZekrModel( zekrTitle: 'أذكار الصباح', zekrImage: 'assets/images/sunrise.png', zekrCat: 'Azkar', screenWidget: AlsabahScreen(), ) ]; // 初始化方法,调用时读取本地存储的收藏状态 Future<void> init() async { _prefs = await SharedPreferences.getInstance(); // 遍历列表,读取每个条目的收藏状态 for (var zekr in _zekrList) { zekr.isFav = _prefs.getBool(zekr.zekrTitle) ?? false; } notifyListeners(); } void updateFav(ZekrModel zekrModel) { bool newFavState = zekrModel.toggleDone(); // 写入本地存储 _prefs.setBool(zekrModel.zekrTitle, newFavState); notifyListeners(); } List<ZekrModel> get zekrList => _zekrList; List<ZekrModel> get favZekr { return _zekrList.where((element) => element.isFav).toList(); } }
注意:需要在应用启动时调用ZekrProvider的init方法加载本地状态,比如在main函数中初始化Provider后调用,或者在首页的initState中调用。
步骤3:修正UI层调用
原有代码传递zekrIndex给需要ZekrModel类型参数的updateFav方法会报错,修正为两种可选写法:
- 传对应下标的model:
onTap: (){ value.updateFav(value.zekrList[zekrIndex]); },
- 或者直接传当前遍历到的ZekrModel实例:
onTap: (){ value.updateFav(currentZekrModel); },
内容的提问来源于stack exchange,提问作者Amr El-Baroudy
相关产品推荐
相关产品推荐

