我正在使用flutter和firebase构建一个一对一聊天应用程序,我想像在所有主要聊天应用程序上一样,在发生当天的标签下显示所有聊天。毫无疑问,我通过在每条消息的时间戳字段上使用order by命令,以时间升序从firestore中检索数据。但是如何显示不同日期的日期标签。目前,我正在使用pub.dev的grouped_list包将聊天划分为不同的组,但我希望自己处理逻辑,有没有同样的方法可以通过flutter中的list.viewbuilder实现。
在我看来,以前的方法不适用于使用后端数据的真实应用程序。我们应该动态地用日期分隔列表。只需简单的检查就可以简单明了地完成。
像这样的
ListView.builder(
reverse: true,
itemBuilder: (context, int index) {
/// separate feed by dates
Widget separator = SizedBox();
if (index != 0 && messages[index].createdAt.day != messages[index - 1].createdAt.day) {
separator = Container(
height: 2,
width: Get.width,
color: Colors.black,
);
}
return Column(
children: [
separator,
MessageBubbleWidget(messages[index]),
],
);
});
对于在flutter签出中对List
进行分组,请使用集合包中的groupBy
方法。
它是这样工作的:
List<Message> messages = [
Message(
time: DateTime.fromMillisecondsSinceEpoch(1597044941000),
content: "Message 1",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1597044941000),
content: "Message 2",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1597044941000),
content: "Message 3",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1596958541000),
content: "Message 4",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1596958541000),
content: "Message 5",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1596872141000),
content: "Message 6",
),
Message(
time: DateTime.fromMillisecondsSinceEpoch(1596872141000),
content: "Message 7",
),
];
Map<String, List<Message>> grouped =
groupBy<Message, String>(messages, (message) {
DateTime time = message.time;
return "${time.day}.${time.month}.${time.year}";
});
分组后,您可以使用ListView.builder
两次。外部的是标题,内部的是信息。
像这样:
return ListView.builder(
shrinkWrap: true,
itemCount: grouped.keys.length,
itemBuilder: (context, index) {
String date = grouped.keys.toList()[index];
List<Message> messages = grouped[date];
return Column(
children: [
Text(
date,
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
ListView.builder(
primary: false,
itemCount: messages.length,
itemBuilder: (context, index) => Text(
"Message: ${messages[index]}",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.normal)))
],
);
}
);
您可以自己预先拆分消息。输入将是具有分配给每个消息的初始时间戳的List<Message>
,输出将是List<List<Message>>
,其中每天是外部List
中的一个项目。内部List
将存储当天的消息,示例代码可能如下所示:
List<Message> allMessages = await retrieveMessagesFromDataSource();
List<List<Message>> groupedMessages = [];
List<Message> messagesForCurrentDay = [];
DateTime currentDay = allMessages[0].date;
for(Message m in allMessages) {
if(m.date == currentDay)
messagesForCurrentDay.add(m);
else {
groupedMessages.add(messagesForCurrentDay);
messagesForCurrentDay = [];
messagesForCurrentDay.add(m);
currentDay = m.date;
}
}