すらぼうの開発ノート

モバイルアプリエンジニアのメモ

【Flutter】FutureBuilderの使い方

FutureBuilderとは

api.flutter.dev

FutureBuilderは非同期で値が決定するFutureデータやStreamデータを扱うためウィジェット


使い所

ウィジェットビルドする際に、非同期に決定するデータが含まれている場合便利。

Flutterはbuildメソッドを実行することでUIを構成する。 しかしbuildメソッド内にFutureデータを扱いたい場合、 FutureBuilderで、Futureデータが使用されるウィジェットをラップすることで 「Futureの値が決定する前にビルドしてエラー」となることを防いでくれる。


使い方

基本形

FutureBuilderの基本的な使い方は以下。

FutureBuilder<T>(
  future: ... // Future<T>型を返すメソッド
  builder: (context, snapshot) {
    return ...  // ビルドするウィジェット
})
  • future: Futureデータを返すメソッドを指定
  • builder : ビルドしたいウィジェットをreturnで返す。 この時にsnapshotインスタンスを用いて条件分岐を作ることができる(これがFutureBuilderを用いる大きなメリット)

snapshotインスタンスの活用

snapshotインスタンスのプロパティを用いることで、 データ表示処理を管理することができる。 以下で各プロパティの使用方法を説明する。

connectionState

api.flutter.dev

futureで指定された非同期データ生成の状態を取得できる。

以下の状態が存在する。

  • wating : futureで指定したメソッドから渡させるデータを待っている状態
  • done : futureで指定したメソッドからデータを受け取った状態
  • active : streamなどでデータを受け取っている途中の状態
  • none : futureにnullが指定されている状態

上記の中でwatingとdoneを用いた例を示す。 ConnectionStateがwatingの時にはローディングアニメーション、 doneになったらsnapshotのデータを表示する場合は次のように記述できる。

FutureBuilder<T>(
    future: ...  // Future<T>型を返すメソッド ,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        // ConnectionState: waiting
        return ...; // ローディングアニメーションのウィジェット
      } else {
        // ConnectionState: done
        return Text(snapshot.data.toString()); // snapshotのデータを表示
      }
    })

hasData

futureに指定したメソッドがデータを返却したかどうかを判定できる。

  • true: メソッドからnull以外の値が返ってきた状態
  • false: メソッドからnullまたは値が返ってきていない状態

データの返却状態で表示を変えたい場合は以下の様に記述できる。

FutureBuilder<T>(
    future: ...  // Future<T>型を返すメソッド ,
    builder: (context, snapshot) {
      if(snapshot.hasData){
        // データが返却された
        return ...;
      } else {
        // データが返却されていない
        return ...;
      }
    })

data

futureで指定したメソッドが返却したデータを取得できる。

connectionStateの項で示した例でも使用されている。(★の部分)

FutureBuilder<T>(
    future: ...  // Future<T>型を返すメソッド ,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        // ConnectionState: waiting
        return ...; // ローディングアニメーションのウィジェット
      } else {
        // ConnectionState: done
        return Text(snapshot.data.toString()); // ★snapshotのデータを表示
      }
    })