skip to Main Content

I use a stream builder to fetch my list of messages from the remote database.

Q1) When hasData, I’d like the SingleChildScrollViewto scroll down to the last message I am supposed to display in the build, so that the user sees the last message.

How to do that?

Q2) How to setState((){}) the number of items fetched from the StreamBuild?


  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        key: _streamBuilderKey,
        stream: ClassifiedAdMessage.getAdMessagesStream(adId: widget.adId),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          }
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return const CircularProgressIndicatorWithOptions();
            default:
              if (snapshot.data!.docs.isEmpty) {
                return const Center(child: Text("No message so far"));
              }

              final messages = snapshot.data!.docs.map((doc) {
                final map = doc.data();
                return ClassifiedAdMessage.fromMap(map);
              });

              // blah blah

              }

              return Scaffold(
                appBar: AppBar(),
                body: SingleChildScrollView(
                  controller: _scrollController,
                  child: Column(
                    children: [
                      // blah blah
                  ])
                )
              )

2

Answers


  1. Chosen as BEST ANSWER

    I finally mange to do it.

    The key point is to add a callback function to the post frame binder: this event is triggered once the build is performed. Therefore I take this opportunity —as the content is already set— to jump to the end.

    Here is the code:

     @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((_) {
          scrollToBottom();
        });
      }
    
      void scrollToBottom() {
        Future.delayed(const Duration(milliseconds: 200)).then((_) {
          if (!_scrollController.hasClients) return;
          _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
        });
      }
    

  2. What you could do is using the ScrollController in your SingleChildScrollView. When you successfully fetched your data from the server you can use the controller to scroll to the bottom of your scroll view.

    For example:

    scrollController.jumpTo(scrollController.position.minScrollExtent)
    

    You could also use animateTo instead of jumpTo. I recommend the flutter docs to get more information.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search