0

I have a chat screen, and I want to send message, on send message the list view should scroll down to the bottom to the last message that it's sent. please help me

here is the body

      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(),
            ],
          ),
        ),
      ),

here we write the message and send it

  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,
                    ),
                  )),
            ),
            SizedBox(
              width: 0.02 * MediaQuery.of(context).size.width,
            ),
          ],
        ),
      );

  myTextFormField() => Expanded(
        child: SizedBox(
          width: 0.6 * MediaQuery.of(context).size.width,
          height: 0.08 * MediaQuery.of(context).size.height,
          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(){

}

as you see the last function is scrollToBottom(){} but it's empty, so what should I write in

Husamuldeen
  • 439
  • 1
  • 8
  • 21

1 Answers1

0

See you dont have to implement a seperate function to you know show messages in a down to bottom. You can directly start from the bottom as we do in Instagram or whatsapp you just need to use reverse:true as mentioned bellow and you will achieve that

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]);
                },
              ),

Now if you want to scroll to a particular location with some animation , this is a way not the best but since we dont have to scroll to a particular index of chat we can use this so

declare this in the stateful widget

final _controller = ScrollController();

Now on your listview.builder use this as

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

Now on your onpressed or any function use this

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

You need to supply the height you want to scroll to so this may have a disadvantage but then scrolling to top would require height= 0 ;

You can also follow this discussion here

Krish Bhanushali
  • 1,594
  • 1
  • 8
  • 16