【Flutter】Widget of the Week #6 FutureBuilder

【Flutter】Widget of the Week #6 FutureBuilder

どーも!りゅうです(「・ω・)「

今回紹介するのは、
Googleさん公式Youtube「Widget of the Week」で紹介されている、
ウィジェットのサンプル集第6弾は FutureBuilder です!

FutureBuilder ってなに?

FutureBuilderとは、
「非同期処理」をしてくれるウィジェットです\_(・ω・`)ココ重要!

公式からの説明は以下の通り。

Future の価値を表示するのにウィジェットが必要ですか?FutureBuilderをお試しください。Future と builder を使うことで、未来のステータスに応じたウィジェットを作成し、状況の変化によってアップデートすることができます。

公式Youtubeより引用

非同期 ってなに?

非同期処理とは、
「タスクAの処理の反応を待たずにタスクBの処理をする」仕組みのことです\_(・ω・`)ココ重要!

非同期 と 同期 の違いは?

非同期は主に通信時に使われる言葉ですが、
例えば、Webページを表示待ちの時に、
Webページが表示される前に他のアクションができるのが「非同期通信」
Webページが表示されるまで何もアクションできないのが「同期通信」となります。

実は私生活の中でも非同期、同期処理的な事をしています!
例えば、以下のタスク(家事)を実行したいとします。
・洗濯する
・洗濯物を干す
・ご飯を炊く
・料理をする(おかずをつくる)
・掃除

この時のタスクの動きを時系列で見てみるとこんな感じ。

Point

炊飯と洗濯というタスクを機械に任せるのが「非同期」な処理で、
自分だけでは同時進行出来ないタスクが「同期」処理というイメージです!

公式の動画で概要を把握

前置きが長くなりましたが、非同期の仕組みを理解したところで、
1分程度の公式の動画「Widget of the Week」を見て概要を確認しましょう!

概要をなんとなく把握できたところで、
サンプルコードを見ていきましょう(∩’-‘⊂)シュッ

Sample Code

コピペで動くサンプルコードの紹介です!

FutureBuilder

公式を参考(まるコピ)にしたサンプルコードです!

アプリを起動したら、
ローディングのインジケーターが表示された後に
「データのロードが完了しました!」と表示されるシンプルなアプリです。

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(
title: Text('【Flutter#6】FutureBuilder(非同期)'),
),
body: MyStatefulWidget(),
));
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key? key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
Future<String> _calculation = Future<String>.delayed(
// 擬似的に通信中を表現するために3秒遅らせる
Duration(seconds: 3),
() => 'Data Loaded',
);
Widget build(BuildContext context) {
return DefaultTextStyle.merge(
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
child: FutureBuilder<String>(
future: _calculation, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
List<Widget> children;
//snapshotに本当にデータが格納されているかをsnapshot.hasDataで確認
if (snapshot.hasData) {
children = <Widget>[
Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
//「snapshot.data」futureにセットしたメソッドがreturnしてくれる値(今回の場合は"Data Loaded")を取得
child: Text('Result: ${snapshot.data}',
style: TextStyle(color: Colors.red,)),
)
];
//snapshotにデータが格納されていなかった場合
} else if (snapshot.hasError) {
children = <Widget>[
Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}',
style: TextStyle(
color: Colors.red,)),
)
];
//ロード中
} else {
children = <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
const Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...',
style: TextStyle(
color: Colors.red,)),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
},
),
);
}
}

・構造をざっくり解説!!
❶FutureBuilderのfutureに、非同期処理するメソッドを設置する(今回でいう「_calculation」)
❷FutureBuilderのbuilder内でデータ格納有無を判定し、データ取得できたら上記のfutureを呼ぶ
※構造説明の為に、文字装飾等のWidgetは省いています。

Properties

通信状態の確認やエラーハンドリング時に使えそうなプロパティを紹介していきます( *˙ω˙*)و グッ!

プロパティ名 効果
future: Future, ここに非同期処理したい処理を配置
builder: AsyncWidgetBuilder, builder内でエラーハンドリングを行います。

snapshot.connectionState
通信状態を取得する
通信完了したらインジケーターを表示したりする処理に使う(以下例)
if (snapshot.connectionState != ConnectionState.done){インジケーター表示}

snapshot.hasData
nullではない正常な値があるかを確認する。
値がある場合 snapshot.data でfutureメソッド内の処理を返す

snapshot.hasError
nullではない異常な値があるかを確認する。
値がある場合 snapshot.error でエラーを表示する

もっと詳しく知りたい方は 公式ドキュメントをご参考に!

あとがき

お疲れ様でした!
これで通信時の非同期処理マスターに近づきましたね(∩’-‘⊂)シュッ
※async/awaitについてはまた別記事か、後日更新いたします。
次回は FadeTransitionの紹介です!
それでは次の記事で会いましょう!

Flutterカテゴリの最新記事

Buy Me A Coffee