问题描述
我一定做错了什么,但是当我在 ReorderableListView 中重新排列选中的复选框时,它正在为未选中的磁贴设置动画:
这是我正在使用的示例代码:
ReorderableListView(
padding: const EdgeInsets.symmetric(horizontal: 40),children: <Widget>[
for (int index = 0; index < _items.length; index++)
ListTile(
leading: Check@R_502_6277@(
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);
});
完整的code here!
我怎样才能正确地做到这一点? 干杯!
解决方法
我刚刚意识到我的错误,使用 key: Key('$index') 是错误的,因为它正在更改 onReorder,所以 flutter 将我的旧选中的 Checkbox 值与新的未选中的 Checkbox 匹配(我的错误 =|)。只需在 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]}'),
,
首先,您只需要 ListTile
上的键,因为它们是 ReorderableListView
的直接后代。
其次,key需要非索引型。您可以使用 UniqueKey
或 GlobalKey
,但最佳做法是使用 ValueKey
,在该索引处传递值。
就你而言:
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
final List<int> _items = List<int>.generate(2,(int index) => index);
@override
Widget build(BuildContext context) {
return ReorderableListView(
padding: const EdgeInsets.symmetric(horizontal: 40),children: <Widget>[
for (int index = 0; index < _items.length; index++)
ListTile(
leading: Checkbox(
onChanged: (v) => null,// here
key: ValueKey(_items[index]),],onReorder: (int oldIndex,int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex,item);
});
},);
}
}
至于为什么您的索引键不起作用 - 我的理解是在小部件重建后(通过重新排序列表),您的 ListTile
被键入错误的索引(因为该 {{1 }} 已经改变)。当您使用该值时,它是一个可用于标识小部件的常量。
Emily Fortuna 在 Medium 上写了一篇关于键的 wonderful article,如果您打算继续使用 Flutter 进行开发,我强烈建议您阅读。