1. ホーム
  2. flutter

[解決済み] ListViewの最後までプログラム的にスクロールさせる

2022-04-21 02:32:42

質問

スクロール可能な ListView ここで、項目の数は動的に変更することができます。新しい項目がリストの末尾に追加されるたびに、プログラムによって ListView を最後まで表示します。(例: チャットメッセージリストのように、新しいメッセージを最後に追加できるようなもの)

私が思うに、このような場合に必要なのが ScrollController の中で State オブジェクトを作成し、それを手動で ListView のコンストラクタを呼び出すことができます。 animateTo() / jumpTo() メソッドをコントローラ上で実行します。しかし、最大スクロールオフセットを簡単に決定することができないため、単純に scrollToEnd() タイプの操作を行うことができます。 0.0 で初期位置までスクロールさせることができます)。

これを簡単に実現する方法はありますか?

使用方法 reverse: true に収まる項目が少ない場合、項目を上部に整列させたいので、完璧な解決策ではありません。 ListView ビューポートに表示されます。

解決方法は?

を使用する場合、シュリンクラップは 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),
          );
        }
      ),
    );
  }
}