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

Flutter 中 GetStorage 存储列表时修改元素无法持久保存问题求助

问题定位
  • 监听对象不匹配:控制器中ever监听的是counter变量,但初始定义的待持久化列表变量为tile,若二者不是同一变量,监听回调完全不会触发。
  • RxList监听机制限制:RxList默认仅会在列表元素增、删、替换、重排等修改列表本身结构的操作时触发更新通知,修改列表内部单个对象的属性属于对象内部变更,不会触发RxList的更新事件,导致ever回调不会执行,最新数据不会写入GetStorage。
  • 序列化逻辑错误:写入GetStorage时直接传入自定义类TileClass的实例列表,GetStorage无法直接序列化自定义类对象,必须转换为JSON格式的Map才能正常存储。
解决方案

1. 完善TileClass的序列化逻辑

给TileClass实现toJson和fromJson方法,注意Color类型需要转为int值存储:

class TileClass {
  int number;
  String tileName;
  int resetValue;
  String tag;
  int add;
  int substract;
  Color color;

  TileClass({
    required this.number,
    required this.tileName,
    required this.resetValue,
    required this.tag,
    required this.add,
    required this.substract,
    required this.color,
  });

  Map<String, dynamic> toJson() {
    return {
      'number': number,
      'tileName': tileName,
      'resetValue': resetValue,
      'tag': tag,
      'add': add,
      'substract': substract,
      'color': color.value,
    };
  }

  factory TileClass.fromJson(Map<String, dynamic> json) {
    return TileClass(
      number: json['number'] as int,
      tileName: json['tileName'] as String,
      resetValue: json['resetValue'] as int,
      tag: json['tag'] as String,
      add: json['add'] as int,
      substract: json['substract'] as int,
      color: Color(json['color'] as int),
    );
  }
}

2. 修正持久化监听逻辑

确认ever监听的是实际操作的列表变量,写入存储时先将所有元素转为JSON格式:

// 请替换为你实际的列表变量名,如果是counter就写counter
ever(tile, (_) {
  storage.write('tileData', tile.map((e) => e.toJson()).toList());
});

3. 触发RxList更新通知

修改列表内部对象属性后,需要手动触发RxList的更新,两种方案二选一即可:

方案A:手动刷新RxList

修改完属性后调用refresh方法触发更新:

onSubstract: () {
  tileIndex.number = tileIndex.number - tileIndex.substract;
  // 手动触发列表更新
  controller.tile.refresh();
  controller.update();
},
onAdd: () {
  controller.addAudio();
  tileIndex.number += tileIndex.add;
  // 手动触发列表更新
  controller.tile.refresh();
  controller.update();
},

方案B:替换列表元素

构造新的TileClass对象替换对应索引的元素,RxList会自动检测到元素变更触发更新:
首先在控制器中新增修改方法:

void updateTile(int index, int newNumber) {
  final oldTile = tile[index];
  tile[index] = TileClass(
    number: newNumber,
    tileName: oldTile.tileName,
    resetValue: oldTile.resetValue,
    tag: oldTile.tag,
    add: oldTile.add,
    substract: oldTile.substract,
    color: oldTile.color,
  );
  update();
}

然后在UI中调用该方法:

onSubstract: () {
  final newNumber = tileIndex.number - tileIndex.substract;
  controller.updateTile(index, newNumber);
},
onAdd: () {
  controller.addAudio();
  final newNumber = tileIndex.number + tileIndex.add;
  controller.updateTile(index, newNumber);
},

额外优化建议

同时使用GetBuilder和Obx属于冗余用法,二者选其一即可,避免状态管理逻辑混乱。

内容的提问来源于stack exchange,提问作者Phanuel Mensah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:48:03