如何将 Stream 传递给 GroupedListView Flutter
How to pass Stream to GroupedListView Flutter
我目前正在开发我的应用程序的消息部分。我将 streambuilder 和流与 GroupedListView 结合使用,以便可以根据日期对消息进行分组。
但是,我遇到了一些问题,因为 GroupedListView 将列表作为其 'elements' 参数。我们知道流不一定是列表。我研究过将流转换为列表,但似乎找不到解决方案。
代码如下所示:
Expanded( //so that we can move the text field to the bottom
child: StreamBuilder(
stream: db.chatStream(widget.receiverUser.uid),
builder: (context, snapshot) {
return GroupedListView<Chat, DateTime>(
reverse: true, //so that the texts start from bottom to top
order: GroupedListOrder.DESC, //get the proper order of sent messages
padding: const EdgeInsets.all(8),
elements: db.chatStream(widget.receiverUser.uid), //THIS IS WHERE THE PROBLEM IS!!!
groupBy: (chat) => DateTime(
chat.dateTime.year,
chat.dateTime.month,
chat.dateTime.day
),
groupHeaderBuilder: (Chat chat) => SizedBox(
height: 40,
child: Center(
child: Card(
color: Colors.black45,
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
DateFormat.yMMMd().format(chat.dateTime),
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
),
),
),
itemBuilder: (context, Chat chat) {
bool isMe = chat.senderId == uid;
return Align(
alignment: isMe ? Alignment.centerRight
: Alignment.centerLeft,
child: Column(
children: [
Align(
alignment: isMe ? Alignment.centerRight
: Alignment.centerLeft,
child: Card(
color: isMe
? Colors.purpleAccent
: Colors.white,
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
chat.message,
style: TextStyle(
color: isMe
? Colors.white
: Colors.black
),
),
),
),
),
Align(
alignment: isMe
? Alignment.topRight
: Alignment.topLeft,
child: Padding(
padding: isMe ? const EdgeInsets.only(
right: 12)
: const EdgeInsets.only(left: 12),
child: MidText(text: DateFormat('kk:mm').format(
chat.dateTime)),
)
)
],
),
);
}
);
}
),
),
有没有办法将流转换为列表,以便我可以将其传递给“元素”参数?或者我需要采取不同的方法吗?
我也遇到过这个 SO post 但它没有答案。但这基本上也是我同样的问题:
Example
非常感谢任何帮助!
我不确定你问的是否存在。但是我要做的是创建一个 Stream<List<_YourType_>>
并根据给定的快照,我将使用 data
作为我的列表。
PS:如果你像 StreamBuilder<List<_YourType_>>(...
一样初始化你的 StreamBuilder
那么你的快照将是一个 AsyncSnapshot<List<_YourType_>>
并且它的数据值已经是一个 List<_YourType_>
无需投射或任何东西!
PS2:如果我是你,我会寻找 time package 因为它有一个 .date
getter 用于 DateTime
甚至创建你自己喜欢:
extension DateTimeExtension on DateTime {
DateTime get date => isUtc ? DateTime.utc(year, month, day) : DateTime(year, month, day);
}
只是为了更容易获得不包含时间的日期。
您可能应该将 StreamBuilder 声明为 StreamBuilder。您将 运行 出错,指出对象无法访问资源。
我目前正在开发我的应用程序的消息部分。我将 streambuilder 和流与 GroupedListView 结合使用,以便可以根据日期对消息进行分组。
但是,我遇到了一些问题,因为 GroupedListView 将列表作为其 'elements' 参数。我们知道流不一定是列表。我研究过将流转换为列表,但似乎找不到解决方案。
代码如下所示:
Expanded( //so that we can move the text field to the bottom
child: StreamBuilder(
stream: db.chatStream(widget.receiverUser.uid),
builder: (context, snapshot) {
return GroupedListView<Chat, DateTime>(
reverse: true, //so that the texts start from bottom to top
order: GroupedListOrder.DESC, //get the proper order of sent messages
padding: const EdgeInsets.all(8),
elements: db.chatStream(widget.receiverUser.uid), //THIS IS WHERE THE PROBLEM IS!!!
groupBy: (chat) => DateTime(
chat.dateTime.year,
chat.dateTime.month,
chat.dateTime.day
),
groupHeaderBuilder: (Chat chat) => SizedBox(
height: 40,
child: Center(
child: Card(
color: Colors.black45,
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
DateFormat.yMMMd().format(chat.dateTime),
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
),
),
),
itemBuilder: (context, Chat chat) {
bool isMe = chat.senderId == uid;
return Align(
alignment: isMe ? Alignment.centerRight
: Alignment.centerLeft,
child: Column(
children: [
Align(
alignment: isMe ? Alignment.centerRight
: Alignment.centerLeft,
child: Card(
color: isMe
? Colors.purpleAccent
: Colors.white,
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
chat.message,
style: TextStyle(
color: isMe
? Colors.white
: Colors.black
),
),
),
),
),
Align(
alignment: isMe
? Alignment.topRight
: Alignment.topLeft,
child: Padding(
padding: isMe ? const EdgeInsets.only(
right: 12)
: const EdgeInsets.only(left: 12),
child: MidText(text: DateFormat('kk:mm').format(
chat.dateTime)),
)
)
],
),
);
}
);
}
),
),
有没有办法将流转换为列表,以便我可以将其传递给“元素”参数?或者我需要采取不同的方法吗? 我也遇到过这个 SO post 但它没有答案。但这基本上也是我同样的问题: Example
非常感谢任何帮助!
我不确定你问的是否存在。但是我要做的是创建一个 Stream<List<_YourType_>>
并根据给定的快照,我将使用 data
作为我的列表。
PS:如果你像 StreamBuilder<List<_YourType_>>(...
一样初始化你的 StreamBuilder
那么你的快照将是一个 AsyncSnapshot<List<_YourType_>>
并且它的数据值已经是一个 List<_YourType_>
无需投射或任何东西!
PS2:如果我是你,我会寻找 time package 因为它有一个 .date
getter 用于 DateTime
甚至创建你自己喜欢:
extension DateTimeExtension on DateTime {
DateTime get date => isUtc ? DateTime.utc(year, month, day) : DateTime(year, month, day);
}
只是为了更容易获得不包含时间的日期。
您可能应该将 StreamBuilder 声明为 StreamBuilder。您将 运行 出错,指出对象无法访问资源。