Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”
Posted
技术标签:
【中文标题】Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”【英文标题】:Flutter/Firestore - Implementing a "pagination" on a dynamic listview in a streambuilder 【发布时间】: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? (解决了,现在只剩下上面的主要问题了)
【问题讨论】:
【参考方案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();
【讨论】:
以上是关于Flutter/Firestore - 在流构建器中的动态列表视图上实现“分页”的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Firestore StreamBuilder 最初获得空值
Flutter/Firestore:“QuerySnapshot”类没有实例获取器“document”