I'm using GroupedListView
(which is based on ListView.builder
) to implement a chat.
I have a ChatBloc
bloc that is responsible to handle new messages from the DataLayer. Whenever new messages are added, I'm emitting a new state of elements, and rebuild the whole ListView.
Here is my code:
child: BlocBuilder<ChatBloc, ChatState>(
builder: (context, state) {
final userId = context.read<AppBloc>().state.user.userId;
return GroupedListView<Message, DateTime>(
controller: scrollController,
elements: state.messages,
reverse: true,
cacheExtent: 9999,
order: GroupedListOrder.DESC,
itemComparator: (element1, element2) =>
element1.timestamp.compareTo(element2.timestamp),
itemBuilder: (context, element) =>
element.messageToWidget(userId, state.senders),
groupBy: (element) => DateTime(
element.timestamp.year,
element.timestamp.month,
element.timestamp.day,
),
groupHeaderBuilder: (element) => Center(
child: TitleMessage(
text: dateFormat03.format(element.timestamp),
),
),
);
},
)
The problem is that I don't want to rebuild everything again with every new message that is added to the list.
I want to build new messages only.
How do I do that using Bloc state management?
Update
According to @Harsimran Singh
ListView.builder
does not recycle its elements on refresh (even due adding a unique Key to each element).
Using ListView.custom
with SliverChildBuilderDelegate
seems not to solve the issue:
Here is my code:
return ListView.custom(
physics: const AlwaysScrollableScrollPhysics(),
childrenDelegate: SliverChildBuilderDelegate(
(context, index) {
final message = state.messages.elementAt(index);
return message.messageToWidget(
userId: userId,
senders: state.senders,
key: Key(message.toString()),
);
},
childCount: state.messages.length,
findChildIndexCallback: (key) {
return state.messages
.indexWhere((e) => Key(e.toString()) == key);
},
),
);
I debugged the code and the findChildIndexCallback
works just fine and returns the correct index. But according to the above video, you can see that the elements are still rendered.
Why is that?