【问题标题】:How to display a stream of list from a bloc using a listview如何使用列表视图显示来自块的列表流
【发布时间】:2020-03-06 14:57:48
【问题描述】:

我正在开发一个即时消息应用程序,我需要用户实时发送和接收消息。我使用 Firebase 作为应用后端,使用 flutter_bloc 包来管理状态,并使用流来实时发送和接收消息。

我已经成功实现了发送消息功能,并且能够从 Cloud Firestore 成功检索消息,但是当用户发送消息时,它并没有加载到聊天消息中ListView

这是在ChatBloc 中调用的ChatProvider getCurrentChatMessages() 方法的实现。

  Stream<List<ChatMessage>> getCurrentChatMessages() {
    return this.messagesRef.orderBy('timestamp', descending: true)
    .snapshots()
    .map((QuerySnapshot snapshot) {
      return snapshot.documents.map<ChatMessage>((DocumentSnapshot snapshot) => ChatMessage.fromFirestore(snapshot)).toList();
    });
  }

ChatProvider 中,这些是将聊天消息列表传播到 UI 的方法

  Stream<ChatState> mapFetchCurrentChatMessagesEventToState(FetchCurrentChatMessagesEvent event) async* {
    yield FetchingCurrentChatMessagesState();
    final bool chatExists = await _chatProvider.chatExists;
    // If chat does not exists create chat.
    if (!chatExists) {
      await _chatProvider.createChat();
    }
    _chatProvider.getCurrentChatMessages().listen((List<ChatMessage> chatMessages) {
      print('Chat messages length: ${chatMessages.length}');
      dispatch(FetchedCurrentChatMessagesEvent(chatMessages));
    });
  }

  Stream<ChatState> mapFetchedCurrentChatMessagesEventToState(FetchedCurrentChatMessagesEvent event) async* {
    final List<ChatMessage> chatMessages = event.chatMessages;
    yield FetchedCurrentChatMessagesState(chatMessages);
  }

这是显示聊天消息的ListView

class ChatMessagesList extends StatefulWidget {
  @override
  _ChatMessagesListState createState() => _ChatMessagesListState();
}

class _ChatMessagesListState extends State<ChatMessagesList> {
  List<ChatMessage> _chatMessages = List<ChatMessage>();

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: BlocBuilder<ChatBloc, ChatState>(
        condition: (ChatState oldState, ChatState newState) => oldState.hashCode != newState.hashCode,
        builder: (BuildContext context, ChatState state) {
          if (state is FetchingCurrentChatMessagesState) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }

          if (state is FetchedCurrentChatMessagesState) {
            _chatMessages = state.chatMessages;
          }

          if (_chatMessages.length == 0) {
            return Container();
          }

          print('Chat Messages:\n$_chatMessages');

          return ListView.builder(
            reverse: true,
            itemCount: _chatMessages.length,
            itemBuilder: (BuildContext context, int index) {
              final ChatMessage chatMessage = _chatMessages[index];
              return ChatMessageTile(
                chatMessage: chatMessage,
              );
            },
          );
        },
      ),
    );
  }
}

每当发送消息时,ChatBloc 会将更新的聊天消息列表发送到 ChatMessagesList 小部件,但小部件无法相应更新。它只显示_chatMessages 列表中的第一个元素,直到我看到poppush 路由,也就是我看到更新的列表时。

我希望当用户单击发送消息按钮时,聊天消息列表会更新为已发送消息。

【问题讨论】:

    标签: flutter dart stream bloc


    【解决方案1】:

    使用 rxdart 的包流控制器,例如 BehaviourSubject,您可以使用您的列表 bloc 类中的示例:

    final _list = BehaviourSubject<List<ChatMessage>>(); //private variable
    Observable<List<ChatMessage>> get list => _list.stream; //exposesvariable_publicly
    
    exampleMethod(){ 
    //prepare your list and when ready load the stream using sink
    _list.sink.add(readylist);
    }
    

    现在在你的 listview 上使用 streambuilder

    Widget _listView(){
     return StreamBuilder(){
       stream: blocProvider.list
       builder: (context, AsyncSnapshot<List<ChatMessage>> listSnapShot){
         //custom build your UI now with data in listSnapshot.data.
    
       }
    

    希望这会有所帮助。

    【讨论】:

    • 您好,感谢您的回复。 bloc 实际上填充了列表。但问题在于当我想在ListView 中显示它时,它一直显示列表中的第一个元素,直到我poppush 路由,也就是当我得到完整的元素时列表显示。
    • 您好,我已经尝试过您的解决方案,但问题仍然存在,ChatBloc 将聊天消息发送到ChatListWidget,但ListView 无法将其子代更新为新的聊天消息。
    猜你喜欢
    • 2020-07-13
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    相关资源
    最近更新 更多