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

Flutter中如何将对象列表的布尔收藏状态存储到Shared Preferences

实现SharedPreferences持久化收藏状态方案

前置准备

首先在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:15:03