小编典典

以编程方式滚动到 ListView 的末尾

all

我有一个可滚动ListView的项目数量可以动态变化的地方。每当将新项目添加到列表末尾时,我想以编程方式将其滚动ListView到末尾。(例如,可以在末尾添加新消息的聊天消息列表之类的东西)

我的猜测是我需要ScrollController在我的State对象中创建一个并将其手动传递给ListView构造函数,这样我以后可以在控制器上调用animateTo()/jumpTo()方法。但是,由于我无法轻松确定最大滚动偏移量,因此似乎不可能简单地执行一种scrollToEnd()操作(而我可以轻松通过0.0使其滚动到初始位置)。

有没有简单的方法来实现这一目标?

使用reverse: true对我来说不是一个完美的解决方案,因为我希望当只有少量项目适合ListView视口时,项目在顶部对齐。


阅读 72

收藏
2022-07-12

共1个答案

小编典典

如果您使用带有 的收缩包装ListViewreverse: true则将其滚动到 0.0 即可满足您的要求。

import 'dart:collection';

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Example',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> _messages = <Widget>[new Text('hello'), new Text('world')];
  ScrollController _scrollController = new ScrollController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new Container(
          decoration: new BoxDecoration(backgroundColor: Colors.blueGrey.shade100),
          width: 100.0,
          height: 100.0,
          child: new Column(
            children: [
              new Flexible(
                child: new ListView(
                  controller: _scrollController,
                  reverse: true,
                  shrinkWrap: true,
                  children: new UnmodifiableListView(_messages),
                ),
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.add),
        onPressed: () {
          setState(() {
            _messages.insert(0, new Text("message ${_messages.length}"));
          });
          _scrollController.animateTo(
            0.0,
            curve: Curves.easeOut,
            duration: const Duration(milliseconds: 300),
          );
        }
      ),
    );
  }
}
2022-07-12