サンプルアプリの概要
今回、使用するサンプルアプリは図1のようなアプリです。画面は3つありますが、すべて同じ画面であり、また、そのふるまいも同じです。
ただし、以下のように3つのアーキテクチャを使って実装します。それらの違いについて、アーキテクチャの構造とコード面から違いを見てほしいと思います。
- Stateのみを用いる方法
- 変更(イベント)通知(ProviderとChangeNotifier/Consumer)を用いる方法
- BLoCパターン(ProviderとStreamController/StreamBuilder)を用いる方法
Stateのみを用いる方法
この方法はアーキテクチャと呼べるかわかりませんが、最も基本となる知識のみを使って実装する方法です。後で紹介する他の2つの方法と比べて、どこが変わるかを知っていただくために最初に紹介します。
また、このコードの構造を簡易的に示したのが図2です。
class _SimpleScreen extends State<SimpleScreen>{
// (1) Stateで管理する変数
bool _loading = true;
List<DateItem> _week = [];
@override
void initState() {
super.initState();
// (2) 初期化時にデータをロード
_loadData();
}
// (3) データをロードする処理
void _loadData() async{
var res = await http.get(Uri.parse("http://192.168.1.1/list.json"),headers: {
'Accept' : 'application/json'
});
setState(() {
var json = jsonDecode(utf8.decode(res.bodyBytes));
_loading = false;
_week = json['items'].map<DateItem>((e) => DateItem.fromJson(e)).toList();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('サンプル(1)'),
actions: [
// (4) リロード処理
IconButton(onPressed: _loading? null :(){
setState(() {
_loading = true;
});
_loadData();
}, icon: const Icon(Icons.refresh))
],
),
// (5) 画面の表示
body: Stack(
children: [
Column(
children : _createListChildren(context),
),
if(_loading)
loadingWidget(context)
]
),
);
}
// (6) Loading 画面を表示
Widget loadingWidget(BuildContext context){
return Container(
: (省略)
);
}
// (7) 5日分のColumnを表示
Widget listWidget(BuildContext context){
return Center(
child: Column(
children : _createListChildren(context)
),
);
}
List<Widget> _createListChildren(BuildContext context){
var _list = <Widget>[];
for(var i = 0; i < _week.length; i++){
DateItem item = _week[i];
// (8) 週(月〜金)の1日を表示するウィジェット
_list.add(DateBlock(item: item));
}
return _list;
}
}
class SimpleScreen extends StatefulWidget{
// : (省略)
}
(1)がState管理する変数です。この変数の値が変わったら画面が更新されます。画面が最初に作成されるタイミングでデータを取得しなければならないので、(2)のinitState()メソッドで(3)のようにデータを取得します。
また、(4)ではリロードボタンを押されたタイミングでも再度データを取得します。画面表示(5)では、Stackを用いてローディング表示を通常の画面の上に置くようにしています。
(6)がローディング画面の実装、(7)が5日分を縦に並べたColumn表示をしています。そして(8)が1日分の表示処理です。この(6)〜(8)までの処理は今回の内容とはあまり関係がなく、このプログラムの重要な点は(2)の_loadData()メソッドになります。
各画面部品を表示する実装はこの後紹介する方法でも、ほぼ同様のため、このコードと違うところに着目して、他のコードを見るようにしてください。
