【问题标题】:Flutter/Firestore - Implementing a "pagination" on a dynamic listview in a streambuilderFlutter/Firestore - 在流构建器中的动态列表视图上实现“分页”
【发布时间】:2019-10-25 03:38:06
【问题描述】:

我想出了逻辑并且它可以工作,但是我遗漏了一些东西,因为这种工作的唯一方法是当我用下一个“页面”或文档替换数组时,但是当我对它执行 .addAll() 时,它得到杂乱。相同的第一个文档被读取,一些新文档也被包含在内,但并不是所有应该包含的内容。

代码:

ScrollController _scrollController = ScrollController();
List<Message> _messages = [];
List<dynamic> _startAfter = [DateTime.now()];

...

@override
void initState() {
    super.initState();
    this._scrollController.addListener(() {
      if (this._scrollController.position.minScrollExtent + this._scrollController.position.pixels <= -15.0) {
        setState(() {
          this._startAfter = [this._messages.first.createdAt.toDate()];
        });
      }
    });
}

...

Column(
  children: <Widget>[
    Expanded(
      child: StreamBuilder<List<Message>>(
          stream: APIs().chats.messagesStream(chatID: widget.chat.chatID, orderBy: 'createdAt', descending: true, startAfter: this._startAfter, limit: 10),
          builder: (context, snapshot) {
            print(this._startAfter);
            switch (snapshot.connectionState) {
              case ConnectionState.waiting:
                {
                  return PAIndicator();
                }
              default:
                {
                  if (snapshot.hasData) {    
                    this._messages = snapshot.data; // Having the issue here.

                    // this._messages.addAll(snapshot.data); Causes problems when rebuilding

                    return MessagesList(
                      scrollController: this._scrollController,
                      messages: this._messages,
                      aUser: widget.aUser,
                    );
                  } else {
                    return ListView();
                  }
                }
            }
          }),
    ),
  // ...
  ]
)

我注意到该错误仅在重建时发生。

当检索到数据时,它会替换数组中的内容,当使用.addAll() 时,我如何只追加数据而不是仅仅替换它或给出相同消息的多个相同值,而不用担心 ui 被重建,比如键盘显示和关闭?

另外,如果没有更多文档,我如何确保它不会被重建或调用 firebase? (解决了,现在只剩下上面的主要问题了)

【问题讨论】:

    标签: listview flutter google-cloud-firestore chat stream-builder


    【解决方案1】:

    为任何需要它的人找出解决方案。唯一的问题是这些项目只是被添加到列表中,所以它看起来不太适合 UI/UX。如果你们都有,请随意添加该解决方案。我尝试了 AnimatedList,但由于状态问题,它不起作用,我还不知道有什么解决方法。

    注意:由于某些原因,它没有收听来自任何一个用户的新消息,我必须重新进入聊天才能看到新消息,请帮忙。

    GlobalKey<AnimatedListState> _listKey = GlobalKey();
    ScrollController _scrollController = ScrollController();
    List<Message> _messages = [];
    List<dynamic> _startAfter = [DateTime.now()];
    int _messagesLimit = 10;
    bool _hasMoreMessages = false;
    
    @override
    void initState() {
      super.initState();
    
      if (Platform.isIOS) {
        this._scrollController.addListener(() {
          if (this._scrollController.position.pixels >= this._scrollController.position.maxScrollExtent + 150.0) {
            this._checkForOldMessages();
          }
        });
      }
    }
    
    @override
    Widget build(BuildContext context) {
      Widget w = WillPopScope(
          child: Stack(
            children: <Widget>[
              Column(
                children: <Widget>[
                  Expanded(child: this._streamBuilderWidget()),
                  // …
                ],
              ),
            ],
          ),
          onWillPop: () {});
    
      …
    }
    
    Widget _streamBuilderWidget() {
        return StreamBuilder<List<Message>>(
            initialData: this._messages,
            stream: APIs().chats.messagesStream(chatID: widget.chat.chatID, orderBy: 'createdAt', descending: true, startAfter: this._startAfter, limit: this._messagesLimit),
            builder: (context, snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting:
                  {
                    return PAIndicator();
                  }
                default:
                  {
                    if (snapshot.data.length < this._messagesLimit) {
                      this._hasMoreMessages = false;
                    } else {
                      this._hasMoreMessages = true;
                    }
    
                    snapshot.data.forEach((m) {
                      print(m.message);
                    });
    
                    if (!ListEquality().equals(this._messages, snapshot.data)) {
                      snapshot.data.forEach((m) {
                        this._messages.add(m);
                      });
                    } else {
                      print('nonononono');
                    }
    
                    // Doesn't Work...
                    // if (mounted) this._listKey.currentState.insertItem(this._messages.length - 1, duration: Duration(milliseconds: 500)); 
    
                    return Platform.isIOS
                        ? MessagesList(mKey: this._listKey, scrollController: this._scrollController, messages: this._messages, aUser: widget.aUser)
                        : RefreshIndicator(
                        child: MessagesList(mKey: this._listKey, scrollController: this._scrollController, messages: this._messages, aUser: widget.aUser),
                        onRefresh: () async {
                          await Future.delayed(Duration(seconds: 1));
    
                          this._checkForOldMessages();
    
                          return null;
                        });
                  }
              }
            });
      }
    
    _checkForOldMessages() {
      if (this._hasMoreMessages) {
        print('Adding More...');
        setState(() {
          this._startAfter = [this._messages.last.createdAt.toDate()];
        });
        this._streamBuilderWidget();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-12-18
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 2017-12-21
      • 2021-12-11
      • 2018-05-29
      相关资源
      最近更新 更多