Flutterでオーバースクロールでの画面更新を可能にするRefreshIndicatorの使い方

公開日:2019/05/16 更新日:2019/05/16
Flutterでオーバースクロールでの画面更新を可能にするRefreshIndicatorの使い方のサムネイル

sven-662061-unsplash.jpg Photo by Sven on Unsplash

はじめに

スマートフォンのアプリでよく目にする機能の1つとして、画面を本来の長さ以上にスクロールする(オーバースクロール)と画面が更新される機能があると思います。Flutterではデフォルトでこの機能を使用することができ非常に簡単に実装することができます。この記事ではこの機能の実装手順をまとめます。

できるようになること

以下のGIF画像のように、画面でオーバースクロールすると更新中のマークが表示され、任意の処理をオーバースクロール時に実行できるようになります。ここでは、簡単な処理として、オーバースクロールされた時間を表示するようにしています。

RefreshIndicator-demo-flutter.gif

このデモのコードは以下のGitHubにあげてあります。

github.com

RefreshIndicator sample

前提と環境

以下の通りです。

  • Flutter 1.5.4-hotfix.2
  • Dart 2.3.0

RefreshIndicatorについて

このオーバースクロールで画面を更新する、または任意の処理を実行する機能は、FlutterのRefreshIndicatorというウィジェットで定義されています。RefreshIndicatorは、スクロールできる要素を含む形で実装します。公式ドキュメントではScrollable(スクローラブル)な要素と表現されており、スクローラブルな要素としてListViewSingleSchildScrollViewが挙げられています。RefreshIndicatorはこれらの要素を包んだ状態で使います。逆に言えばRefreshIndicatorは、中にスクローラブルな要素が含まれていないと動作しません。 なお、RefreshIndicatorは別途パッケージをインストールする必要はなく、デフォルトで使用可能です。

以下がRefreshIndicatorの公式ドキュメントです。

docs.flutter.io

A widget that supports the Material "swipe to refresh" idiom.

RefreshIndicatorの使い方

使い方は非常に簡単です。冒頭に載せたデモのように一番シンプルな使い方の場合、作業としては以下の2つのみです。

  • RefreshIndicatorListViewなどのスクローラブルな要素を包む
  • RefreshIndicatorで包んだ要素がオーバースクロールされた時に実行する関数を定義する

上記についてそれぞれ説明します。 

スクローラブルな要素をRefreshIndicatorで包む

以下のように、ListViewRefreshIndicatorで包みます。以下でonRefresh:というオプションがあり、これに渡された関数がオーバースクロールされた時に実行される関数になります。すなわち、以下の場合はオーバースクロール時に_onRefreshという関数が呼び出され実行されます。

main.dart
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: new RefreshIndicator(
          onRefresh: _onRefresh,
          child: ListView(
            physics: const AlwaysScrollableScrollPhysics(),
            padding: const EdgeInsets.all(8.0),
            children: [
              Container(
                padding: const EdgeInsets.all(16.0),
                height: 50,
                color: Colors.amber[600],
                child: Text("Updated at - " + updated_at.toString()),
              ),
            ],
          )),
    );
}

オーバースクロールされた時に実行する関数を定義する

オーバースクロールされた時に実行する関数を例えば以下のように定義します。以下では、単純に適当な変数のupdated_atに実行時の時間を格納しています。

main.dart
class _MyHomePageState extends State {
DateTime updated_at = new DateTime.now();

Future _onRefresh() async {
    setState(() {
      updated_at = new DateTime.now();
    });
}

@override
  Widget build(BuildContext context) {
return Scaffold(
(...以下省略...)

そしてこの記事の載せたデモでは、このupdated_atを以下のようにそのままテキストで出力するようにしています。

main.dart
child: Text("Updated at - " + updated_at.toString()),

スクロールできるほどの長さがない画面の対応について

もしスクロールできるほど画面が長くない場合は、AlwaysScrollableScrollPhysics()というオプションをListViewなどのスクローラブルな要素の中で指定します。このオプションを設定することで、画面の長さに関わらず常にスクロール機能が使えるようになり、同時にRefreshIndicatorも機能します。

main.dart
body: new RefreshIndicator(
  onRefresh: _onMyRefresh,
    child: ListView(
      physics: const AlwaysScrollableScrollPhysics(), // このオプションを指定
(...以下省略...)

まとめ

ここでは簡単なデモになりましたが、RefreshIndicatorを使ってスクロールされた時に最新情報を取得するなどよく見る機能を簡単に実装できます。

関連記事

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。