CheckBox 动画在 ReorderableListView 内时不起作用
Posted
技术标签:
【中文标题】CheckBox 动画在 ReorderableListView 内时不起作用【英文标题】:CheckBox animation doesn't work when inside a ReorderableListView 【发布时间】:2020-05-31 04:17:39 【问题描述】:我正在尝试制作一个简单的任务列表,其中包含文本和一个复选框,并允许您重新排序任务。重新排序的所有逻辑都在工作,但是在选择任务时复选框更新而不运行动画。
我遇到了一个类似于简单列表 (ListView) 的问题,通过放置一个 ObjectKey 问题得到了解决。在这个例子中,如你所见,还有一个 Key,但动画不起作用。有什么建议吗?
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
title: 'Flutter To Do',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomePage(),
));
class HomePage extends StatefulWidget
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<HomePage>
List myItems = [];
@override
void initState()
super.initState();
for (int i = 0; i < 10; i++)
Map<String, dynamic> newTask = Map();
newTask['task'] = 'Task #$i';
newTask['done'] = false;
myItems.add(newTask);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Flutter To Do'),
),
body: ReorderableListView(
children: [
for (final item in myItems)
Card(
key: ObjectKey(item),
margin: EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0)
),
child: Container(
height: 56,
child: Row(
children: <Widget>[
IconButton(icon: Icon(Icons.reorder), onPressed: null),
Expanded(
child: Text(item['task']),
),
Checkbox(
value: item['done'],
onChanged: (value)
setState(()
item['done'] = value;
);
,
)
],
),
),
)
],
onReorder: (oldIndex, newIndex)
setState(()
if (newIndex > oldIndex)
newIndex -= 1;
final item = myItems.removeAt(oldIndex);
myItems.insert(newIndex, item);
);
,
));
【问题讨论】:
【参考方案1】:因为setState
更新了ReorderableListView
,它会重新渲染整个列表,所以它不会算作更改。
您应该只更新 listView 中的一个 listTile。
为此,将您的 listTile 小部件移动到具有自己的 setState
的 Stateful
小部件,并在主页中替换您的卡片:
class _HomePageState extends State<HomePage>
List myItems = [];
@override
void initState()
super.initState();
for (int i = 0; i < 10; i++)
Map<String, dynamic> newTask = Map();
newTask['task'] = 'Task #$i';
newTask['done'] = false;
myItems.add(newTask);
bool a = false;
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Flutter To Do'),
),
body: ReorderableListView(
children: [
for (var item in myItems)
TaskListItem(
key: ObjectKey(item),
item: item,
),
],
onReorder: (oldIndex, newIndex)
setState(()
if (newIndex > oldIndex)
newIndex -= 1;
final item = myItems.removeAt(oldIndex);
myItems.insert(newIndex, item);
);
,
),
);
class TaskListItem extends StatefulWidget
final item;
const TaskListItem(Key key, this.item) : super(key: key);
@override
_TaskListItemState createState() => _TaskListItemState();
class _TaskListItemState extends State<TaskListItem>
@override
Widget build(BuildContext context)
return Card(
margin: EdgeInsets.all(0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
child: Container(
height: 56,
child: Row(
children: <Widget>[
IconButton(icon: Icon(Icons.reorder), onPressed: null),
Expanded(
child: Text(widget.item['task']),
),
Checkbox(
value: widget.item['done'],
onChanged: (value)
setState(()
widget.item['done'] = value;
);
,
)
],
),
),
);
【讨论】:
以上是关于CheckBox 动画在 ReorderableListView 内时不起作用的主要内容,如果未能解决你的问题,请参考以下文章