【问题标题】:Changing property of children don't trigger UI change on Flutter Getx更改子项的属性不会触发 Flutter Getx 上的 UI 更改
【发布时间】:2021-01-21 11:03:24
【问题描述】:

我正在尝试基于对象列表呈现反应式小部件。

我需要当这个对象的子对象的布尔属性发生变化时,应该更新 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;
}));

【问题讨论】:

  • LessonController 中有什么?
  • 一个名为 getLessonsByCourse 的方法填充下面的属性,该属性也存在于控制器中。 final _sectionList = List
    ().obs;获取sectionList => this._sectionList;设置 sectionList(value) => this._sectionList.value = value;
  • @PatrickFreitas 您是否设法解决了您的问题?你是怎么做到的?
  • 是的,很抱歉没有发布我当时找到的解决方法。 GetX 容器监视列表项的更改,因此当您更改其中一项的属性时,列表本身不会更改。为了解决这个问题,我更改了 item 属性,然后我在列表中覆盖了它。我将更新我的问题以提供一个示例。

标签: flutter flutter-layout flutter-get


【解决方案1】:

看起来问题出在这里: this._sectionList.value = value;

试试这个: this._sectionList = value;

【讨论】:

  • 这不是,我想通了。您指定的只是一个封装指令,在其他目的之间,它将用于在每个要使用 sectionList 变量的地方都不需要使用“.value”。
【解决方案2】:

据我所知,Flutter GetX 中的可观察列表并不关心对象本身的内部变化。

为了强制 UI 更新,我不得不将更新后的对象返回到列表中的相同位置,以假装主列表中的对象发生了变化。 p>

类似的东西:

Section tappedSection = _.sectionList[index];
tappedSection.lessons[i].isCompleted = value;
_.notifyLessonProgress(tappedSection.lessons[i].id, value);
_.sectionList[index] = tappedSection;

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多