可关闭的小部件仍然是树的一部分

问题描述 投票:0回答:1

我尝试理解两个有状态小部件之间的行为。 我有一个简单的 listeView,每个 Item 都是一个 ItemTest。我在 ItemTestState 中创建了一个属性,该属性使用 InitState() 中的

widget.item
进行初始化。 使用这段代码,当我尝试删除一个项目时,我得到了一个“可关闭的小部件仍然是树的一部分”,但我不知道为什么。

class DismissibleExample extends StatefulWidget {
  const DismissibleExample({super.key});

  @override
  State<DismissibleExample> createState() => _DismissibleExampleState();
}

class _DismissibleExampleState extends State<DismissibleExample> {
  List<int> items = List<int>.generate(100, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: items.length,
      padding: const EdgeInsets.symmetric(vertical: 16),
      itemBuilder: (BuildContext context, int index) {
        return ItemTest(
            item: items[index],
            onDismissed: () {
              setState(() {
                items.removeAt(index);
              });
            },
        );
      },
    );
  }
}

class ItemTest extends StatefulWidget {
  const ItemTest({
    super.key,
    required this.item,
    required this.onDismissed,
  });

  final int item;
  final Function() onDismissed;

  @override
  State<ItemTest> createState() => _ItemTestState();
}

class _ItemTestState extends State<ItemTest> {
  int item = 0;

  @override
  void initState() {
    item = widget.item;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Dismissible(
      background: Container(
        color: Colors.green,
      ),
      key: ValueKey<int>(item),
      onDismissed: (direction) {
        widget.onDismissed();
      },
      child: ListTile(
        title: Text(
          'Item $item',
        ),
      ),
    );
  }
}

感谢您的帮助

flutter listview statefulwidget
1个回答
0
投票

您面临的问题是由于您处理

key
中的
Dismissible widget
的方式造成的。

您正在

item
方法中使用
widget.item
初始化
initState()
。当小部件重建时,该值不会更新。

return Dismissible(
      background: Container(
        color: Colors.green,
      ),
      key: ValueKey<int>(widget.item),
      onDismissed: (direction) {
        widget.onDismissed();
      },
      child: ListTile(
        title: Text(
          'Item $item',
        ),
      ),
    );
© www.soinside.com 2019 - 2024. All rights reserved.