EddyLee
EddyLee

Reputation: 803

Make FirebaseAnimatedList auto scroll when have new data

I've try to build Chat example on Flutter, but I have problem, how I can make FirebaseAnimatedFlutter auto scroll when have new data populate ?

Example: When I submit new chat message for my friend, from my side, I can call this method to auto scroll:

Timer(Duration(milliseconds: 100), () {
    scrollController.animateTo(
        scrollController.position.maxScrollExtent,
        duration: const Duration(milliseconds: 100),
        curve: Curves.easeOut);
  });

But at my friend side, he still need manual scroll to end to see new message

So, there are anyway to detect and auto scroll to end of FirebaseAnimatedList when we receive new data ?

Thank you

Upvotes: 2

Views: 1174

Answers (3)

Junaid Aslam
Junaid Aslam

Reputation: 84

Just wrap your FirebaseAnimatedList with Flexible Widget & thats it. This worked for me.

Upvotes: 0

EddyLee
EddyLee

Reputation: 803

thank for useful answer of João Soares, i already solve this problem by 2 step

  1. Reverse data from Firebase by use 'sort' property of FirebaseAnimatedList

  2. Set 'reverse' property to 'true' in FirebaseAnimatedList And work like a charm

    FirebaseAnimatedList(
    query: loadChatContent(context, app),
    sort: (DataSnapshot a,DataSnapshot b) => b.key.compareTo(a.key), //fixed
    reverse: true, //fixed
    

Upvotes: 1

J. S.
J. S.

Reputation: 9625

I can't see all your code, but there is a trick you can do that will avoid having to add extra code. It involves reversing the data in the list of messages and setting to true the reverse property of the ListView. This will make the messages move up as new messages come in.

You reverse the original list, you set to true the reverse property of the ListView, and when you add messages to your List you use messages.insert(0, newMessage) to add it to the top (now bottom because of inversion), instead of of messages.add.

class Issue65846722 extends StatefulWidget {
  @override
  _Issue65846722State createState() => _Issue65846722State();
}

class _Issue65846722State extends State<Issue65846722> {
  List<String> messages = [
    'message 1',
    'message 2',
    'message 3',
  ].reversed.toList();
  TextEditingController textEditingController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('StackOverflow'),
      ),
      floatingActionButton: Align(
        alignment: Alignment.topRight,
        child: Padding(
          padding: const EdgeInsets.only(top: 100.0),
          child: FloatingActionButton(
            // To simulate an incoming message from another source that is not
            // the local TextField
            child: Icon(Icons.message),
            onPressed: () => newMessage('new message'),
          ),
        ),
      ),
      body: Column(
        children: [
          Expanded(
            child: ListView.builder(
              reverse: true,
              itemCount: messages.length,
              itemBuilder: (context, index){
                return Container(
                  child: Text(messages[index]),
                );
              },
            ),
          ),
          Divider(color: Colors.black,),
          TextFormField(
            controller: textEditingController,
            onFieldSubmitted: (_) => submitMessage()
          ),
        ],
      ),
    );
  }

  void submitMessage(){
    newMessage(textEditingController.text);
    textEditingController.clear();
  }

  void newMessage(String newMessage){
    setState(() {
      messages.insert(0, newMessage);
    });
  }
}

Upvotes: 1

Related Questions