Flutter 颤振复选框ReorderableListView中的动画错误

Flutter 颤振复选框ReorderableListView中的动画错误,flutter,checkbox,reorderable-list,Flutter,Checkbox,Reorderable List,我一定是做错了什么,但当我在ReorderableListView中重新排序复选框时,它正在为未选中的平铺设置动画: 下面是我正在使用的示例代码: ReorderableListView( padding: const EdgeInsets.symmetric(horizontal: 40), children: <Widget>[ for (int index = 0; index < _items.length; index++) ListTi

我一定是做错了什么,但当我在ReorderableListView中重新排序复选框时,它正在为未选中的平铺设置动画:

下面是我正在使用的示例代码:

ReorderableListView(
  padding: const EdgeInsets.symmetric(horizontal: 40),
  children: <Widget>[
    for (int index = 0; index < _items.length; index++)
      ListTile(
        leading: Checkbox(
          
          key: Key('$index'),
          onChanged: (v) => null,
          value: _items[index].isOdd ? true : false,
        ),
        key: Key('$index'),
        tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
        title: Text('Item ${_items[index]}'),
      ),
  ],
  onReorder: (int oldIndex, int newIndex) {
    setState(() {
      if (oldIndex < newIndex) {
        newIndex -= 1;
      }
      final int item = _items.removeAt(oldIndex);
      _items.insert(newIndex, item);
    });
ReorderableListView(
填充:常量边集。对称(水平:40),
儿童:[
对于(int index=0;index<\u items.length;index++)
列表砖(
前导:复选框(
key:key(“$index”),
一旦更改:(v)=>null,
值:_items[索引].isOdd?true:false,
),
key:key(“$index”),
tileColor:_items[索引]。isOdd?oddItemColor:evenItemColor,
标题:文本('Item${u items[index]}'),
),
],
onReorder:(int-oldIndex,int-newIndex){
设置状态(){
如果(旧索引<新索引){
newIndex-=1;
}
final int item=_items.removeAt(oldIndex);
_项目。插入(新索引,项目);
});
满了

我怎样才能做好呢?
干杯!

我刚刚意识到我的错误,使用key:key(“$index”)是错误的,因为它是在重新排序时更改的,所以flatter将旧的选中复选框值与新的未选中复选框(my bad=|)匹配。只需在ListTile中使用ObjectKey,它就会正确匹配

ListTile(
        leading: Checkbox(
          onChanged: (v) => null,
          value: _items[index].isOdd ? true : false,
        ),
        key: ObjectKey(_items[index]),
        tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
        title: Text('Item ${_items[index]}'),
      ),

首先,您只需要在
listile
上输入一个键,因为它们是
ReorderableListView
的直接后代

其次,键需要基于非索引。您可以使用
UniqueKey
GlobalKey
,但最佳做法是使用
ValueKey
,在该索引处传递值

就你而言:

class\u MyStatefulWidgetState扩展状态{
最终列表_items=List.generate(2,(int-index)=>index);
@凌驾
小部件构建(构建上下文){
返回ReorderableListView(
填充:常量边集。对称(水平:40),
儿童:[
对于(int index=0;index<\u items.length;index++)
列表砖(
前导:复选框(
一旦更改:(v)=>null,
值:_items[索引].isOdd?true:false,
),
//这里
key:ValueKey(_items[索引]),
tileColor:_items[索引]。isOdd?oddItemColor:evenItemColor,
标题:文本('Item${u items[index]}'),
),
],
onReorder:(int-oldIndex,int-newIndex){
设置状态(){
如果(旧索引<新索引){
newIndex-=1;
}
final int item=_items.removeAt(oldIndex);
_项目。插入(新索引,项目);
});
},
);
}
}
至于为什么你的索引键不起作用——我的理解是,在小部件重建后(从重新排列列表开始),你的
ListTile
被键入了错误的索引(因为该
ListTile
的索引已更改)。当你使用该值时,这是一个可以用来识别小部件的常量


Medium上的Emily Fortuna写了一篇关于键的文章,如果您打算继续使用Flatter开发,我强烈建议您阅读。

我刚刚注意到,如果我使用GlobalKey()代替键(“$index”)它保持复选框状态,但我仍然需要了解发生了什么事。嗨,亚历克斯,我的错,我刚刚意识到匹配错误。不用担心,如果你认为这个问题对未来的读者有价值,我建议接受答案。