如何在 Flutter 中更新 AnimatedList 中的数据
Posted
技术标签:
【中文标题】如何在 Flutter 中更新 AnimatedList 中的数据【英文标题】:How to update data in an AnimatedList in Flutter 【发布时间】:2019-06-19 22:42:30 【问题描述】:如何在 Flutter 的 AnimatedList 中更新数据(添加、删除行)?我可以通过更新支持数据并调用setState
在 ListView 中完成此操作。例如,
setState(()
_data.insert(2, 'pig');
);
不过,在 AnimatedList 中似乎更复杂。
【问题讨论】:
【参考方案1】:下面演示了更新 AnimatedList 的各种方法。该过程每次都包括两个主要步骤:
-
更新数据集
通知 AnimatedList 的全局键有关更改
插入单个项目
在索引2
处添加“猪”。
String item = "Pig";
int insertIndex = 2;
_data.insert(insertIndex, item);
_listKey.currentState.insertItem(insertIndex);
插入多个项目
在索引 2 处插入三只动物。
final items = ['Pig', 'Chichen', 'Dog'];
int insertIndex = 2;
_data.insertAll(insertIndex, items);
// This is a bit of a hack because currentState doesn't have
// an insertAll() method.
for (int offset = 0; offset < items.length; offset++)
_listKey.currentState.insertItem(insertIndex + offset);
删除单个项目
从列表中删除“猪”。
int removeIndex = 2;
String removedItem = _data.removeAt(removeIndex);
// This builder is just so that the animation has something
// to work with before it disappears from view since the original
// has already been deleted.
AnimatedListRemovedItemBuilder builder = (context, animation)
// A method to build the Card widget.
return _buildItem(removedItem, animation);
;
_listKey.currentState.removeItem(removeIndex, builder);
删除多个项目
从列表中删除“骆驼”和“绵羊”。
int removeIndex = 2;
int count = 2;
for (int i = 0; i < count; i++)
String removedItem = _data.removeAt(removeIndex);
AnimatedListRemovedItemBuilder builder = (context, animation)
return _buildItem(removedItem, animation);
;
_listKey.currentState.removeItem(removeIndex, builder);
补充代码
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text('Update AnimatedList data')),
body: BodyWidget(),
),
);
class BodyWidget extends StatefulWidget
@override
BodyWidgetState createState()
return new BodyWidgetState();
class BodyWidgetState extends State<BodyWidget>
// the GlobalKey is needed to animate the list
final GlobalKey<AnimatedListState> _listKey = GlobalKey();
// backing data
List<String> _data = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[
SizedBox(
height: 400,
child: AnimatedList(
key: _listKey,
initialItemCount: _data.length,
itemBuilder: (context, index, animation)
return _buildItem(_data[index], animation);
,
),
),
RaisedButton(
child: Text(
'Insert single item',
style: TextStyle(fontSize: 20),
),
onPressed: ()
_onButtonPress();
,
)
],
);
Widget _buildItem(String item, Animation animation)
return SizeTransition(
sizeFactor: animation,
child: Card(
child: ListTile(
title: Text(
item,
style: TextStyle(fontSize: 20),
),
),
),
);
void _onButtonPress()
// replace this with method choice below
_insertSingleItem();
void _insertSingleItem()
String item = "Pig";
int insertIndex = 2;
_data.insert(insertIndex, item);
_listKey.currentState.insertItem(insertIndex);
void _insertMultipleItems()
final items = ['Pig', 'Chichen', 'Dog'];
int insertIndex = 2;
_data.insertAll(insertIndex, items);
// This is a bit of a hack because currentState doesn't have
// an insertAll() method.
for (int offset = 0; offset < items.length; offset++)
_listKey.currentState.insertItem(insertIndex + offset);
void _removeSingleItems()
int removeIndex = 2;
String removedItem = _data.removeAt(removeIndex);
// This builder is just so that the animation has something
// to work with before it disappears from view since the original
// has already been deleted.
AnimatedListRemovedItemBuilder builder = (context, animation)
// A method to build the Card widget.
return _buildItem(removedItem, animation);
;
_listKey.currentState.removeItem(removeIndex, builder);
void _removeMultipleItems()
int removeIndex = 2;
int count = 2;
for (int i = 0; i < count; i++)
String removedItem = _data.removeAt(removeIndex);
AnimatedListRemovedItemBuilder builder = (context, animation)
return _buildItem(removedItem, animation);
;
_listKey.currentState.removeItem(removeIndex, builder);
注意
如果您的列表项包含任何有状态的小部件,那么您需要为它们提供密钥,以便系统可以跟踪它们。 虽然我在写 Medium 文章之前写了这个答案,但我现在维护my answer on Medium。在那里查看最新更新。【讨论】:
是否可以更新索引处的现有数据,而不是删除并重新添加?例如,我在索引处有一个文本,我想更改文本值。我该怎么做? @Rakesh 您可以使用setState
并只更新数据列表。我扩展了我的答案here 来描述这一点。以上是关于如何在 Flutter 中更新 AnimatedList 中的数据的主要内容,如果未能解决你的问题,请参考以下文章
当我向列表视图添加元素时,如何在 Flutter 中更新列表视图?
Flutter-如何在firebase查询中使用逻辑AND以及如何更新数据?
如何更新在 Firebase 托管中部署的 Flutter Web 版本
Flutter:如何使用 Getx Obx 更新标记在谷歌地图中的位置?