我想设置ListView.builder的初始滚动位置,我希望列表从底部0.0
开始
如果我在listView上设置reverse
,我当然会将初始滚动位置设为所需的滚动位置,但是我需要的是让最后一个孩子位于底部,这是一个聊天应用程序。
这是列表生成器,MessageItem()
是聊天消息
ListView.builder(
shrinkWrap: true,
controller: _scrollController,
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(10.0),
itemBuilder: (BuildContext context, int index) =>
MessageItem(
index: index,
document: snapshot.data.documents[index],
myId: myId));
这是某人send
消息
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 500),
curve: Curves.easeOut);
动画工作正常。
我想要的是当用户进入聊天室时列表滚动位置已经在底部。
答案 0 :(得分:2)
为避免错误(在滚动列表未附加任何列表的情况下),请使用WidgetsBinding在构建就绪后拉出。
void _scrollToBottom() {
if (_scrollController.hasClients) {
_scrollController.animateTo(_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300), curve: Curves.elasticOut);
} else {
Timer(Duration(milliseconds: 400), () => _scrollToBottom());
}
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom());
{...} //rest of code;
}
答案 1 :(得分:1)
我感到您很痛苦,因为这是必不可少的要求,因为在一次聊天中可能有成千上万的消息。
要解决此问题,您可以使用
SchedulerBinding.instance.addPostFrameCallback((_){});
构建小部件树后立即触发此回调,因此您只需
scrollController.jump(scrollController.position.maxScrollExtent);
但是,如果您有异步显示消息的功能,那是行不通的,也就是说,在具有某些功能的initstate之后,该功能会将其从firestore文档中拉出。 在这种情况下,您首先需要加载它们,然后再执行上述步骤。希望这会有所帮助。
答案 2 :(得分:0)
您可以设置ScrollController's属性之一:initialScrollOffset
但是在您知道目标项目/索引的偏移位置的情况下。
AboutPage.objects.first()
(请注意,此示例假定列表的窗口小部件的大小是恒定大小,但是如果列表中没有恒定的窗口小部件大小,则您必须能够计算的最终偏移位置您的目标商品-这是另外一个问题)
或者,如果您希望它始终是最后一项/索引,那么它会容易得多:
ScrollController _controller = ScrollController(initialScrollOffset: itemHeight * index)
答案 3 :(得分:0)
对我来说,解决方案是:
SingleChildScrollView(
reverse: true,
child: Container(),
),
ListView也具有反向属性。