0

我正在颤振中创建与 firebase 的聊天,我希望当 listview 构建器完成时,它可以转到列表的末尾(最后一条消息)。

这就是我的构建方法的样子:

return Scaffold(
    backgroundColor: Color(0xFFf1e4e8),
    body: Stack(
      children: [
        Container(
          padding: EdgeInsets.only(bottom: 125),
          child: StreamBuilder(
              stream: userBloc.chat(widget.chatID),
              builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {                    
                if (!snapshot.hasData) {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                } else if(snapshot.connectionState == ConnectionState.done && snapshot.hasData) {                  
                  return ListView.builder(
                    controller: scrollController,
                    physics: BouncingScrollPhysics(),
                    itemCount: snapshot.data.size,
                    itemBuilder: (context, index) {
                      return ChatMessage(
                          isUserMessage: isUserMessage(snapshot,index),
                          message:
                              snapshot.data.docs[index].data()['Message'],
                              timeStamp:snapshot.data.docs[index].data()['Timestamp']);
                    },
                  );
                }
              }),
 );

正确的方法是什么?

4

3 回答 3

1

将 addListener 附加到您的滚动控制器,然后相应地使用 jumpTo 函数。你可以按照这个例子

ScrollController _scrollController;

double _lastEndOfScroll = 0;   

_scrollController.addListener(() {

double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
if (maxScroll == currentScroll) {

   _lastEndOfScroll = maxScroll;
 
}
 });

_scrollController.jumpTo(_lastEndOfScroll);
于 2021-08-11T10:05:29.010 回答
0

在您的 initState() 中,您可以使用addPostFrameCallback注册一个回调,它会在第一帧完成渲染后被调用一次。您可以使用此回调滚动到 ListView 的底部。

@override
void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback( (_) {
     _scrollToBottomOfListView();
  }
}



  
于 2020-11-16T01:32:26.730 回答
0

最简单的解决方案如下:

StreamBuilder(
  stream: FirebaseFirestore.instance
  .collection('<MessagesColection>')
  .orderBy('<Time field>',descending: true)
  .snapshots(),
  builder: (context,snapshot) {                    
      return ListView.builder(
        //The reversed list will put the list backwards. 
        //The start of the list will start at the bottom.
        reverse: true, 
        controller: scrollController,      
        itemCount: snapshot.data.size,
        itemBuilder: (context, index) {                                                    
          return ChatMessage(snapshot);          
        },
      );
    }
),

在前面的代码中,所做的是将列表倒置,最近的消息将在底部,并按降序排列记录,即从最近到最近。这样,最新消息将位于列表的开头(在本例中位于底部),而最少的消息将位于列表底部(在本例中位于顶部)。

于 2020-11-25T00:49:49.953 回答