We are using the GroupedListView package which for the most part seems to be serve what we need in our application. The issue occurs when adding a new record to the Stream that the GroupedListView complains that Bad State: Stream has already been listened to.
Widget buildMessages(convoId) {
return StreamBuilder(
key: widget.key,
stream: DatabaseService.getChatMessages(convoId),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
message = snapshot.data!.docs;
return GroupedListView<dynamic, String>(
reverse: true,
elements: message,
groupBy: (element) =>
DateFormat('yMMdd').format(element['timestamp'].toDate()),
order: GroupedListOrder.DESC,
groupSeparatorBuilder: _createGroupHeader,
itemBuilder: (context, dynamic element) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: _buildMessage(element)),
controller: listScrollController,
);
} else {
return const SizedBox();
}
},
);
}
Widget _createGroupHeader(element) {
if (isToday(DateTime.parse(element))) {
return Container(
padding: const EdgeInsets.all(10),
child: Text(
'Today'.toUpperCase(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelMedium!,
),
);
}
if (isYesterday(DateTime.parse(element))) {
return Container(
padding: const EdgeInsets.all(10),
child: Text(
'Yesterday'.toUpperCase(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelMedium!,
),
);
}
return Container(
padding: const EdgeInsets.all(10),
child: Text(
DateFormat.yMMMd().format(DateTime.parse(element)).toUpperCase(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelMedium!,
),
);
}