どーも!りゅうです(「・ω・)「
今回紹介するのは、
Googleさん公式Youtube「Widget of the Week」で紹介されている、
ウィジェットのサンプル集第6弾は FutureBuilder です!
FutureBuilder ってなに?
FutureBuilderとは、
「非同期処理」をしてくれるウィジェットです\_(・ω・`)ココ重要!
公式からの説明は以下の通り。
Future の価値を表示するのにウィジェットが必要ですか?FutureBuilderをお試しください。Future と builder を使うことで、未来のステータスに応じたウィジェットを作成し、状況の変化によってアップデートすることができます。
公式Youtubeより引用
非同期 ってなに?
非同期処理とは、
「タスクAの処理の反応を待たずにタスクBの処理をする」仕組みのことです\_(・ω・`)ココ重要!
非同期 と 同期 の違いは?
非同期は主に通信時に使われる言葉ですが、
例えば、Webページを表示待ちの時に、
Webページが表示される前に他のアクションができるのが「非同期通信」
Webページが表示されるまで何もアクションできないのが「同期通信」となります。
実は私生活の中でも非同期、同期処理的な事をしています!
例えば、以下のタスク(家事)を実行したいとします。
・洗濯する
・洗濯物を干す
・ご飯を炊く
・料理をする(おかずをつくる)
・掃除
この時のタスクの動きを時系列で見てみるとこんな感じ。
炊飯と洗濯というタスクを機械に任せるのが「非同期」な処理で、
自分だけでは同時進行出来ないタスクが「同期」処理というイメージです!
公式の動画で概要を把握
前置きが長くなりましたが、非同期の仕組みを理解したところで、
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内でエラーハンドリングを行います。
|
もっと詳しく知りたい方は 公式ドキュメントをご参考に!
あとがき
お疲れ様でした!
これで通信時の非同期処理マスターに近づきましたね(∩’-‘⊂)シュッ
※async/awaitについてはまた別記事か、後日更新いたします。
次回は FadeTransitionの紹介です!
それでは次の記事で会いましょう!
コメントを書く
コメントを投稿するにはログインしてください。