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
相关产品推荐
相关产品推荐

