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

Flutter中使用sharedPreferences存取自定义列表bool字段数据

需求可行性结论

完全可以实现,且不需要存储全量列表数据。你的场景中id/num/name属于固定静态数据,硬编码在代码中不会变更,只有like/catched两个bool字段会随用户交互变化,只需要以每条数据的唯一id为标识,单独存储这两个变更的bool值即可,比全量序列化存储性能更好、维护成本更低。

具体实现步骤

1. 引入依赖

在pubspec.yaml中添加本地存储依赖:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

执行flutter pub get完成安装。

2. 修复原有交互逻辑的问题

你原有onTap回调里的写法有两个问题:一是取反操作没有读取当前条目的属性值,二是没有用setState触发UI刷新,修正后的交互逻辑如下:

onTap: () {
  setState(() {
    // 取当前条目的属性值取反
    dlists.like = !dlists.like;
    dlists.catched = !dlists.catched;
    // 修改后立刻同步到本地存储
    _saveSingleItemStatus(dlists);
  });
},

3. 实现单条状态存储方法

导入shared_preferences包,编写存储方法,用条目唯一id拼接存储key,避免和其他存储数据冲突:

import 'package:shared_preferences/shared_preferences.dart';

Future<void> _saveSingleItemStatus(DefinitiveList item) async {
  final prefs = await SharedPreferences.getInstance();
  // 分别存储两个bool字段
  await prefs.setBool('item_${item.id}_like', item.like);
  await prefs.setBool('item_${item.id}_catched', item.catched);
}

4. 实现初始化读取逻辑

在页面的initState生命周期中调用读取方法,把本地存储的状态覆盖到初始静态列表上,完成状态恢复:

@override
void initState() {
  super.initState();
  _loadSavedStatus();
}

Future<void> _loadSavedStatus() async {
  final prefs = await SharedPreferences.getInstance();
  for (final item in definiti) {
    // 如果本地没存过值,就用代码里写的初始默认值
    item.like = prefs.getBool('item_${item.id}_like') ?? item.like;
    item.catched = prefs.getBool('item_${item.id}_catched') ?? item.catched;
  }
  // 状态覆盖完成后刷新UI
  setState(() {});
}

这套逻辑不需要做任何全量列表的序列化操作,只存储变更的bool字段,存储空间占用极小,读写速度快,也不会出现反序列化字段匹配错误的问题。


补充:全量列表序列化存储实现方案

如果后续你的列表数据不是硬编码静态数据(比如从服务端拉取、可能动态调整),必须存储全量列表,可以通过给数据类加Map转换方法实现序列化,步骤如下:

  1. 给DefinitiveList类添加序列化、反序列化方法:
class DefinitiveList {
  int id;
  String num;
  String name;
  bool like;
  bool catched;

  DefinitiveList(
    this.id,
    this.num,
    this.name,
    this.like, 
    this.catched
  );

  // 对象转可存储的Map结构
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'num': num,
      'name': name,
      'like': like,
      'catched': catched,
    };
  }

  // 从Map结构还原对象
  factory DefinitiveList.fromMap(Map<String, dynamic> map) {
    return DefinitiveList(
      map['id'] as int,
      map['num'] as String,
      map['name'] as String,
      map['like'] as bool,
      map['catched'] as bool,
    );
  }
}
  1. 存储时把整个列表转成List<Map>结构,再转成json字符串通过shared_preferences存储;读取时把字符串解码成List<Map>,再通过fromMap方法还原成DefinitiveList对象列表即可。注意你当前的静态列表场景完全不需要用这套方案,前面的轻量存储方案已经完全满足需求。

内容的提问来源于stack exchange,提问作者Juan Sin Miedo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:09:18