Flutter使用GetX开发待办应用时列表复选框点击状态不更新如何解决
问题原因
RxList仅会监听集合自身的元素增减、替换、重排等操作,不会监听集合内部单个元素的属性变更。你修改TaskItem的isChecked属性时,RxList没有触发更新事件,外层Obx也就不会刷新UI。
解决方案
以下提供3种不同适配场景的解决方式:
方案1:手动触发RxList刷新(改动最小,适合小型项目)
修改列表项的onChanged回调,修改属性后调用RxList的refresh()方法手动通知更新:
onChanged: (newValue) { print(newValue); addTaskController.toDoTasksList[index].setChecked(newValue); // 新增这行手动触发列表更新 addTaskController.toDoTasksList.refresh(); },
方案2:替换列表元素(符合响应式规范,性能中等)
先给TaskItem类新增copyWith方法,修改属性时直接替换列表对应位置的元素,RxList会自动监听元素替换事件触发刷新:
首先定义copyWith方法:
class TaskItem { TASK_STATUS taskStatus; bool isChecked; String taskName; TaskItem({required this.taskStatus, required this.isChecked, required this.taskName}); // 新增copyWith方法 TaskItem copyWith({ TASK_STATUS? taskStatus, bool? isChecked, String? taskName, }) { return TaskItem( taskStatus: taskStatus ?? this.taskStatus, isChecked: isChecked ?? this.isChecked, taskName: taskName ?? this.taskName, ); } }
然后修改onChanged回调:
onChanged: (newValue) { final oldTask = addTaskController.toDoTasksList[index]; addTaskController.toDoTasksList[index] = oldTask.copyWith(isChecked: newValue); },
方案3:元素属性转为响应式变量(局部刷新,性能最优,适合长列表)
将TaskItem中需要动态修改的属性改为Rx响应式变量,每个列表项单独用Obx包裹,修改属性时仅刷新对应列表项,不需要刷新整个列表:
- 修改TaskItem定义:
class TaskItem { TASK_STATUS taskStatus; // 将isChecked改为响应式RxBool RxBool isChecked; String taskName; TaskItem({required this.taskStatus, required this.isChecked, required this.taskName}); }
- 新增任务时传入响应式变量:
TaskItem taskItem = TaskItem( taskStatus: TASK_STATUS.TODO, isChecked: false.obs, // 改为.obs创建响应式变量 taskName: title, );
- 修改ListView的itemBuilder,每个列表项单独包裹Obx:
itemBuilder: (context, index) { final task = addTaskController.toDoTasksList[index]; return Obx(() => TaskCheckItem( value: task.isChecked.value, title: task.taskName, onChanged: (newValue) { task.isChecked.value = newValue; }, onDownloadClicked: () {}, onDeleteClicked: () {}, )); },
内容的提问来源于stack exchange,提问作者Faizan Malik
相关产品推荐
相关产品推荐

