I'm want to add new widget (StatefulWidget) to ListView to the top of the list items.insert(0, listItem), but when I do this, all elements of the list are initializing again (initState() hook is calling every time)
If i'm adding the items to bottom of the list items.add(listItem) - everything works as intended (initState() is called only on the newly added element.)
Code for demo purposes
ListItem widget code
class ListItem extends StatefulWidget {
final String label;
const ListItem({Key key, @required this.label}) : super(key: key);
_ListItemState createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
@override
void initState() {
super.initState();
print('initState() ${this.widget.label}');
}
@override
Widget build(BuildContext context) {
return Text(this.widget.label);
}
}
List widget code
Adding new elements occurs inside addItem() function:
class ItemsList extends StatefulWidget {
State<StatefulWidget> createState() => ItemsListState();
}
class ItemsListState extends State<ItemsList> {
var items = List<ListItem>();
@override
Widget build(BuildContext context) {
return GestureDetector(
child: ListView(children: items),
onTap: addItem);
}
void addItem() {
final label = items.length.toString();
print('Add $label');
final listItem = ListItem(key: ValueKey(label), label: label);
items.insert(0, listItem);
this.setState(() {
items = []..addAll(items);
});
}
}
Results
Console output when addItem() function was called 3 times (just for example):
Add 0
initState() 0
Add 1
initState() 1
initState() 0
Add 2
initState() 2
initState() 1
initState() 0
Expected output, when new items appends to bottom of the list (items.add(listItem) instead of items.insert(0, listItem))
Add 0
initState() 0
Add 1
initState() 1
Add 2
initState() 2
Is there any workarounds for this situation? I want to previous added list items staying with old state.
I tried to change axis direction of list viewport to up (changing reverse property of ListView to true) but got the same result.