Flutter 我不知道';我不理解为什么不从窗口小部件树中删除可驳回文件

Flutter 我不知道';我不理解为什么不从窗口小部件树中删除可驳回文件,flutter,Flutter,我试图理解可驳回的小部件,但不知何故,我最终总是得到一条错误消息,即可驳回的小部件仍然是小部件树的一部分。我确实理解错误消息的意思,但我似乎无法实现解决方案 本质上,我的问题是(通过提供程序)在列表中保留项,onDismissed删除该项并重建状态,每个Dismissible的索引是通过索引访问的id。我觉得我对这个理论有点了解,但缺少一个关键部分。如果有人能解释代码的错误,我们将不胜感激 这是我的设置(尽可能简化) 主要 测试屏幕小部件 class TestScreen extends Sta

我试图理解可驳回的小部件,但不知何故,我最终总是得到一条错误消息,即可驳回的小部件仍然是小部件树的一部分。我确实理解错误消息的意思,但我似乎无法实现解决方案

本质上,我的问题是(通过提供程序)在列表中保留项,onDismissed删除该项并重建状态,每个Dismissible的索引是通过索引访问的id。我觉得我对这个理论有点了解,但缺少一个关键部分。如果有人能解释代码的错误,我们将不胜感激

这是我的设置(尽可能简化)

主要

测试屏幕小部件

class TestScreen extends StatefulWidget {
  @override
  _TestScreenState createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  void removeItem(int id) {
    setState(() => Provider.of<TestDataProvider>(context).removeItem(id));
  }

  @override
  Widget build(BuildContext context) {
    final data = Provider.of<TestDataProvider>(context);
    return Scaffold(
      body: ListView.builder(
          itemCount: data.items.length,
          itemBuilder: (context, index) {
            return ChangeNotifierProvider.value(
              value: data.items[index],
              child: Dismissible(
                onDismissed: (_) {
                  removeItem(data.items[index].id);
                },
                key: ValueKey(data.items[index].id),
                child: Card(
                  child: ListTile(
                    title: Text(data.items[index].name),
                    leading: CircleAvatar(
                      child: Text(data.items[index].id.toString()),
                    ),
                  ),
                ),
              ),
            );
          }),
    );
  }
}
class TestScreen扩展StatefulWidget{
@凌驾
_TestScreenState createState();
}
类_TestScreenState扩展状态{
无效删除项(内部id){
setState(()=>Provider.of(context.removietem(id));
}
@凌驾
小部件构建(构建上下文){
最终数据=提供者(上下文);
返回脚手架(
正文:ListView.builder(
itemCount:data.items.length,
itemBuilder:(上下文,索引){
返回ChangeNotifierProvider.value(
值:data.items[索引],
孩子:可鄙(
onDismissed:(uux){
removietem(data.items[index].id);
},
key:ValueKey(data.items[index].id),
孩子:卡片(
孩子:ListTile(
标题:文本(data.items[index].name),
领先:CircleAvatar(
子项:文本(data.items[index].id.toString()),
),
),
),
),
);
}),
);
}
}
TestDataProvider

class TestData with ChangeNotifier {
  final int id;
  final String name;
  TestData(this.id, this.name);
}

class TestDataProvider with ChangeNotifier {
  List<TestData> items = [
    TestData(1, 'test'),
    TestData(2, 'hello'),
    TestData(3, 'stuff'),
    TestData(4, 'mine'),
    TestData(5, 'xxx'),
    TestData(6, 'world'),
    TestData(7, 'blue'),
    TestData(8, 'cloud'),
    TestData(9, 'sky'),
  ];

  void removeItem(int id) => items.removeWhere((element) => element.id == id);
}
使用ChangeNotifier类测试数据{
最终int id;
最后的字符串名;
TestData(this.id,this.name);
}
使用ChangeNotifier类TestDataProvider{
列表项=[
测试数据(1,“测试”),
TestData(2,'你好'),
TestData(3,“stuff”),
测试数据(4,'矿山'),
测试数据(5,'xxx'),
TestData(6,“世界”),
测试数据(7,'蓝色'),
TestData(8,‘云’),
TestData(9,“天空”),
];
void removitem(int id)=>items.removehere((element)=>element.id==id);
}

在可拆卸的内部放置一把钥匙:UniqueKey(),

哦,谢谢,它确实解决了这个问题。尽管如此,我现在还是很困惑:如果你可以只使用UniqueKey,为什么还要使用ValueKey呢?有什么特别的用途吗?据我所知,UniqueKey()实现了ValueKey作为唯一键应该做的技巧,跟踪值。如果你认为我的回答有用,请别忘了投赞成票。
class TestData with ChangeNotifier {
  final int id;
  final String name;
  TestData(this.id, this.name);
}

class TestDataProvider with ChangeNotifier {
  List<TestData> items = [
    TestData(1, 'test'),
    TestData(2, 'hello'),
    TestData(3, 'stuff'),
    TestData(4, 'mine'),
    TestData(5, 'xxx'),
    TestData(6, 'world'),
    TestData(7, 'blue'),
    TestData(8, 'cloud'),
    TestData(9, 'sky'),
  ];

  void removeItem(int id) => items.removeWhere((element) => element.id == id);
}