ReorderableListView 中的 Flutter Checkbox 错误动画
Flutter Checkbox wrong animation inside a ReorderableListView
我一定是做错了什么,但是当我在 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);
});
完整 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需要非index-based。您可以使用 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,
value: _items[index].isOdd ? true : false,
),
// here
key: ValueKey(_items[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);
});
},
);
}
}
至于为什么您的索引键不起作用 - 我的理解是,在小部件重建后(从重新排序列表),您的 ListTile
键控在错误的索引处(因为那个 ListTile
已更改)。当您使用该值时,它是一个常量,可用于识别小部件。
Medium 上的 Emily Fortuna 写了一篇 wonderful article 关于按键的文章,如果您打算继续使用 Flutter 进行开发,我强烈建议您阅读这篇文章。
我一定是做错了什么,但是当我在 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);
});
完整 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需要非index-based。您可以使用 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,
value: _items[index].isOdd ? true : false,
),
// here
key: ValueKey(_items[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);
});
},
);
}
}
至于为什么您的索引键不起作用 - 我的理解是,在小部件重建后(从重新排序列表),您的 ListTile
键控在错误的索引处(因为那个 ListTile
已更改)。当您使用该值时,它是一个常量,可用于识别小部件。
Medium 上的 Emily Fortuna 写了一篇 wonderful article 关于按键的文章,如果您打算继续使用 Flutter 进行开发,我强烈建议您阅读这篇文章。