从 List移动元素后 UI 未正确更新;

发布于 2025-01-11 14:51:25 字数 1609 浏览 0 评论 0原文

我有一个 List; mySet,它是小部件 Entry 的列表。

在父小部件中,我使用 ListView.builder 来生成这些小部件。

这个父小部件有两个附加方法

addEntry() {
  setState(() {
    mySet.add(Entry(index: mySet.length));
  });
}

removeEntry(_EntryState entry) {
  int index = entry.widget.index;
  setState(() {
    mySet.removeWhere((item) => item.index == index);
  });
}

在每个条目中调用这些方法的按钮如下所示

IconButton(
  iconSize: 25,
  icon: Icon(Icons.add),
  onPressed: index == mySet.last.index
      ? () {
          setState(() {
            pKey.currentState!.addEntry();
          });
        }
      : null),
IconButton(
  iconSize: 25,
  icon: Icon(Icons.remove),
  onPressed: isLast(() {
    setState(() {
      pKey.currentState!.removeEntry(this);
    });
  })),

并且此函数

isLast(Function fn) => index == mySet.last.index ? fn : null;

加法和减法函数的条件是相同的,这只是我测试并尝试调试问题。

问题:

当我单击添加行小部件时,前一行的添加/删除按钮被禁用,正如它们应该的那样。

输入图片此处描述

但是,当我单击最后一行上的“删除”时,前一行的按钮不会重新启用。

,如果我对代码(任何内容)进行小更改以触发热重载,则最后一行的按钮将启用。

这是我的 Listview.builder 代码,位于同一个父小部件中。

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return mySet[index];
        },
        itemCount: mySet.length);
  }

I have a List<Entry> mySet, which is a List of widget Entry.

In a parent widget, I use a ListView.builder to generate these widgets.

This parent widget has two additional methods

addEntry() {
  setState(() {
    mySet.add(Entry(index: mySet.length));
  });
}

removeEntry(_EntryState entry) {
  int index = entry.widget.index;
  setState(() {
    mySet.removeWhere((item) => item.index == index);
  });
}

The buttons that call these in each entry look like this

IconButton(
  iconSize: 25,
  icon: Icon(Icons.add),
  onPressed: index == mySet.last.index
      ? () {
          setState(() {
            pKey.currentState!.addEntry();
          });
        }
      : null),
IconButton(
  iconSize: 25,
  icon: Icon(Icons.remove),
  onPressed: isLast(() {
    setState(() {
      pKey.currentState!.removeEntry(this);
    });
  })),

And this function

isLast(Function fn) => index == mySet.last.index ? fn : null;

The condition on the add and subtract functions are identical, this was just me testing and trying to debug the problem.

The problem:

When I click to add a row widget, the prior rows' add/remove buttons are disabled, as they should be.

enter image description here

But when I click remove on the last row, the prior row's buttons are not re-enabled.

enter image description here

Yet if I make a small change to the code (anything), to trigger a hot-reload, the last row's buttons enable.

Here's my Listview.builder code, in the same parent widget.

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return mySet[index];
        },
        itemCount: mySet.length);
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏日浅笑〃 2025-01-18 14:51:25

有问题的用户 Flutter:当删除项目时,ListView 内的小部件值不会更新 也有类似的问题。

在您的情况下,您可以通过使用 ValueKey(property) 来解决此问题,其中 property 是您确定不同的 Entry 对象的属性对于每个条目

确保没有两个条目可以同时具有相同的 property 值,否则 flutter 会抛出错误,因为您将拥有两个相同的 ValueKeys

The user in question Flutter: The widget values ​inside the ListView are not updated when an item is removed has a similar problem.

In your case you can solve this issue by using a ValueKey(property) where property is a a ofttribute your Entry object which you are sure is different for every Entry.

Make sure no two Entries can have the same value for property at the same time as otherwise flutter will throw an Error as you will have two identical ValueKeys.

诺曦 2025-01-18 14:51:25

我通过使用一个跟踪 Entry 实例的数组和一个跟踪相应状态的数组解决了部分问题。

然后我可以为最后一项调用 setState() ,这是我帖子中遇到麻烦的根源。

removeEntry(_Entry entry) {
  theSetStates.removeWhere((v) => v == entry);
  theSet.removeWhere((v) => v == entry.widget);
  setState(() {});
  theSetStates.last.setState(() {});
}

如果有更简单的方法来获取小部件实例的列表。请告诉我。谷歌没有发现任何东西。

I solved part of the problem by having one array that tracked instances of Entry, and one array to track corresponding states.

I could then call setState() for the last item which was the source of my trouble in my post.

removeEntry(_Entry entry) {
  theSetStates.removeWhere((v) => v == entry);
  theSet.removeWhere((v) => v == entry.widget);
  setState(() {});
  theSetStates.last.setState(() {});
}

If there's an easier way to get a list of instances of a Widget. Please let me know. Google didn't turn up anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文