我正在尝试基于对象列表呈现反应式小部件。
我需要当这个对象的子对象的布尔属性发生变化时,应该更新 UI。
在这种情况下,我的控制器有一个 os Sections 列表,每个部分都有一个 Lessons 列表。
为了更好地理解,我根据我的需要重写了我的代码,制作了一个简单的例子。我已经尝试使用 .map、.forEach 和其他方法,但是 children 属性永远不会触发 UI 更新。
GetX<LessonController>(
initState: (state) => controller.getLessonsByCourse(course.id),
builder: (_) {
return Expanded(
child: ListView.separated(
scrollDirection: Axis.vertical,
itemCount: _.sectionList.length,
itemBuilder: (BuildContext context, int index) {
return ExpansionTile(
title: Text(_.sectionList[index].title),
children: <Widget>[
for(var i = 0; i < _.sectionList[index].lessons.length; i++)
Padding(
padding: const EdgeInsets.all(8.0),
child:
Obx(() =>
GestureDetector(
child: Text((_.sectionList[index].lessons[i] as Lesson).isCompleted.toString()),
onTap: () {
(_.sectionList[index].lessons[i] as Lesson).isCompleted = !(_.sectionList[index].lessons[i]as Lesson).isCompleted;
print((_.sectionList[index].lessons[i]as Lesson).isCompleted.toString());
})
),
)
]);
},
separatorBuilder: (context, ind) => Divider(
height: 2,
color: Colors.grey[300],
),
),
);
})
解决方案:
GetX 容器监视列表项的更改,因此当您更改其中一项的属性时,列表本身不会更改。为了解决这个问题,我更改了 item 属性,然后我在列表中覆盖了它。
onTap: (value) {
Section tappedSection = _.sectionList[index];
tappedSection.lessons[lessonIndex].isCompleted = value;
// This is the secret
// Making GetX detect a change on the list and rebuild UI
_.sectionList[index] = tappedSection;
}));