Flutter修改ValueNotifier数据后ValueListenableBuilder未重绘Widget问题求助
问题根因
- ValueNotifier内部默认采用浅对比判断值是否变化,你持有的
List<String>是可变集合,直接调用add()、removeAt()等方法修改集合内部元素时,List的内存引用地址没有变化,ValueNotifier会判定值未更新,不会触发notifyListeners(),因此绑定的ValueListenableBuilder不会重绘。 - 代码存在两处额外问题:
- 在
Tabbypin的initState中重新给全局global.pincode赋值,会覆盖全局初始化的实例,导致原有监听失效 - 在
Tabbypin和MenuBar的dispose中重复释放global.pincode,会引发重复释放异常,且页面销毁后全局变量就无法再使用
- 在
修复方案
1. 修正集合修改逻辑
所有修改global.pincode的地方都要赋值新的List实例,不要直接修改原集合内部元素,赋值新值时ValueNotifier会自动触发通知,不需要手动调用notifyListeners():
- 文本框添加邮编逻辑(
EnterText组件的Add按钮点击事件)
原代码:
global.pincode.value.add(pin);
替换为:
global.pincode.value = List.from(global.pincode.value)..add(pin);
- 左滑删除邮编逻辑(
Dismissible的onDismissed回调)
原代码:
global.pincode.value.removeAt(index);
替换为:
global.pincode.value = List.from(global.pincode.value)..removeAt(index);
2. 清理冗余代码
- 删除
Tabbypin的initState中以下行:
global.pincode = ValueNotifier<List<String>>(['Select Pin']);
全局变量已经提前初始化,无需在页面初始化时重复赋值
- 删除
MenuBar的dispose中以下行:
global.pincode.dispose();
全局ValueNotifier仅需在整个应用生命周期结束时释放一次即可,无需在单个页面销毁时释放
修改完成后,每次操作列表都会生成新的List实例,ValueNotifier会自动检测到值变化,触发所有绑定的ValueListenableBuilder重绘。
内容的提问来源于stack exchange,提问作者Nimish Khattar
相关产品推荐
相关产品推荐

