Flutter - ListView.builder:初始滚动位置

Irv*_*nta 12 listview chat native dart flutter

我想设置 ListView.builder 的初始滚动位置,我希望列表从底部开始 0.0

如果我reverse在 listView 上进行设置,我当然会得到初始滚动位置是所需的位置,但我需要的是将最后一个孩子放在底部,这是一个聊天应用程序。

这是列表生成器,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));

Run Code Online (Sandbox Code Playgroud)

这是我收到send消息时的动画


_scrollController.animateTo(
                _scrollController.position.maxScrollExtent,
                duration: const Duration(milliseconds: 500),
                curve: Curves.easeOut);
Run Code Online (Sandbox Code Playgroud)

动画工作正常。


我想要的是当用户进入聊天室时列表滚动位置已经在底部。

TWL*_*TWL 11

您可以设置ScrollController 的属性之一:initialScrollOffset

但前提是您知道目标项/索引的偏移位置。

ScrollController _controller = ScrollController(initialScrollOffset: itemHeight * index)
Run Code Online (Sandbox Code Playgroud)

请注意,此示例假设列表小部件的大小是恒定大小,但如果列表中没有恒定小部件大小,那么您必须能够计算目标项目的最终偏移位置 - 并且是另一个问题

或者,如果您希望它始终是最后一个项目/索引,那么就容易多了:

ScrollController _controller = ScrollController(initialScrollOffset: _controller.position.maxScrollExtent)
Run Code Online (Sandbox Code Playgroud)

  • 构建时不能使用 _controller (8认同)

Car*_*Mar 8

我的解决方案是:

SingleChildScrollView(
                reverse: true,
                child: Container(),
              ),
Run Code Online (Sandbox Code Playgroud)

ListView也有reverse属性。

  • 您还应该反转您的数组消息。 (3认同)

Rod*_*igo 7

为避免任何列表未附加滚动的错误,请在构建准备好后使用 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这个答案没有得到更多的喜爱。这解决了我在 ListView 中选择复选框并保持视图静态而不是总是跳回顶部时遇到的问题。谢谢! (2认同)