如何在发送消息时滚动聊天屏幕

问题描述

我有一个聊天屏幕,我想发送消息,在发送消息时,列表视图应向下滚动到底部,直到它发送的最后一条消息。 请帮助我

这是尸体

      body: WillPopScope(
        onWillPop: pressBack,child: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[
              SizedBox(
                height: 0.02 * MediaQuery.of(context).size.height,),Expanded(
                child: SizedBox(
                  width: 0.9 * MediaQuery.of(context).size.width,child: ListView.builder(
                    controller: _scrollController,itemCount: messageList.length + 1,itemBuilder: (BuildContext context,index) {
                      return index == 0
                          ? Container()
                          : oneMessage(messageList[index - 1]);
                    },SizedBox(
                height: 0.02 * MediaQuery.of(context).size.height,texWriteInBottomBar(),],

我们在这里编写消息并发送

  texWriteInBottomBar() => Container(
        width: MediaQuery.of(context).size.width,height: 0.08 * MediaQuery.of(context).size.height,child: Row(
          mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[
            SizedBox(
              width: 0.04 * MediaQuery.of(context).size.width,myTextFormField(),SizedBox(
              width: 0.02 * MediaQuery.of(context).size.width,GestureDetector(
              onTap: sendMessage,child: SizedBox(
                  height: 0.1 * MediaQuery.of(context).size.height,width: 0.1 * MediaQuery.of(context).size.height,child: Transform(
                    alignment: Alignment.center,transform: (getTranslated(context,'language')=='ar')?Matrix4.rotationY(math.pi):Matrix4.rotationX(0),child: Image.asset(
                      'assets/images/Chat/send.png',fit: BoxFit.fitHeight,)),);

  myTextFormField() => Expanded(
        child: SizedBox(
          width: 0.6 * MediaQuery.of(context).size.width,child: TextFormField(
            controller: _textEditingController,onChanged: (text) {
              setState(() {
                messageText = _textEditingController.text;
              });
            },onFieldSubmitted: (text) {
              sendMessage();
            },textAlign: TextAlign.right,decoration: Inputdecoration(
              border: decor,focusedBorder: decor,enabledBorder: decor,errorBorder: decor,disabledBorder: decor,fillColor: Color(0xffF3F3F3),filled: true,hintText: getTranslated(context,'Say something'),hintStyle: TextStyle(
                color: Color(0xff909090),fontFamily: 'Cairo',);
  void sendMessage() async {
    setState(() {
      messageList.add(Message(
          messageText,'','${DateTime.Now().year} ${DateTime.Now().month} ${DateTime.Now().day} ','${DateTime.Now().hour} : ${DateTime.Now().minute}',widget.sender));
      _textEditingController.text = '';
    });
    scrollToBottom();
  }
scrollToBottom(){

}

您看到的最后一个函数是scrollToBottom(){},但它为空,所以我应该写什么

解决方法

您不必知道要从头到尾显示消息,就不必实施单独的功能。您可以直接从底部开始,就像我们在Instagram或仅需使用的whatsapp中所做的一样 reverse:true就像下面提到的那样,您将实现这一目标

ListView.builder(
                reverse: true,//Add this and your work is done
                controller: _scrollController,itemCount: messageList.length + 1,itemBuilder: (BuildContext context,index) {
                  return index == 0
                      ? Container()
                      : oneMessage(messageList[index - 1]);
                },),

现在,如果您想滚动到带有动画的特定位置,这不是最好的方法,但是由于我们不必滚动到特定的聊天索引,因此可以使用此功能

在有状态窗口小部件中对此进行声明

final _controller = ScrollController();

现在您的listview.builder上将其用作

ListView.builder(
          controller: _controller,//add this controller
....),

现在您已按下或任何功能 用这个

_animateToIndex(height) => _controller.animateTo(height,duration: Duration(seconds: 2),curve: Curves.fastOutSlowIn);

您需要提供要滚动到的高度,所以这可能有一个缺点,但然后滚动到顶部将需要height = 0;

您也可以关注此讨论 here