I have a web-socket that sends images with some data and than I display them inside AnimatedList
. The problem is that every new data comes in, it reload every single item the list which reloads every image. Also because image is from base64 converted, it can't be cashed.
Is there any way to preserve the state of each object in AnimatedList
so that when new item is added, it doesn't reload all other objects/images in the list.
AnimatedList
sample:
AnimatedList(
key: node.validListKey,
controller: widget.scrollController,
padding: EdgeInsets.fromLTRB(10, 10, 0, 10),
initialItemCount: node.data.length,
itemBuilder: (context, index, animation) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
curve: Interval(0, 0.2, curve: Curves.ease)),
child: SizeTransition(
sizeFactor:
CurvedAnimation(parent: animation, curve: Curves.ease),
child: DataContainer(data[index])
),
);
},
),
Base decode sample:
child: AspectRatio(
aspectRatio: 1 / 1,
child: ExtendedImage.memory(
base64.decode(data.base),
fit: BoxFit.cover,
loadStateChanged: (state) {
if (state.extendedImageLoadState ==
LoadState.completed) {
return ExtendedRawImage(
image: state.extendedImageInfo?.image,
);
}
return Center(child: CircularProgressIndicator());
},
),
),
UPDATE#1 It seems that the problem is about how I insert items in the list. Because I insert new items at start of the list, for some reason it calls init state only for the last element, but not the recently added one. When I insert at the end of the list, problem is solved. Is there any way how I could force to call init state for the recently added item instead of the last?
Insert item example:
array.add(data);
array.insert(0, data);
if (key.currentState != null)
key.currentState.insertItem(0, duration: _insertDuation);
UPDATE#2
So I was able to fix the first problem that my images was reloading by wrapping AnimatedList
inside SingleChildScrollView
, adding reverse: true
, shrinkWrap: true
and by adding decode
inside initState
method.
SingleChildScrollView(
child : ListView.builer(
shrinkWrap: true,
reverse: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
...
},
)
);
But now the problem is with remove
method. When I try to remove item from the list, base widget content stays the same, but image changes by one index. I have tried adding unique key for each widget, but that forces to reload each image when data has been added.
_data.removeAt(0);
if (_validListKey.currentState != null)
_validListKey.currentState.removeItem(
0, (context, animation) => Container(),
duration: Duration.zero);
node.validListKey
that changes.AnimatedList
does not destroy the state of your list items – Rémi RousseletProvider
package to manage my states and key forAnimatedList
(final NodeHelper node = Provider.of<NodeHelper>(context, listen: false);
). Can that be a problem? – Mārtiņš Ciekurs