How do you update data (add, remove rows) in an AnimatedList in Flutter? I can do it in a ListView by just updating the backing data and calling setState
. For example,
setState(() {
_data.insert(2, 'pig');
});
It seems more complicated in an AnimatedList, though.
The various ways to update the AnimatedList are demonstrated below. The process includes two main steps every time:
Add "Pig" at index 2
.
String item = "Pig";
int insertIndex = 2;
_data.insert(insertIndex, item);
_listKey.currentState.insertItem(insertIndex);
Insert three animals at index 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);
}
Remove "Pig" from the list.
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);
Remove "Camel" and "Sheep" from the list.
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);
}
}
}
Note