SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Flutterで始めるモバイルアプリ開発

【Flutter解説】データをもとに画面処理を行う方法──ビジネスロジックと画面処理のアーキテクチャを知ろう

Flutterで始めるモバイルアプリ開発 第24回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 前回までは、データを保存する方法と取得する方法などについて紹介しました。今回は、取得したデータをもとに画面処理を行う方法について紹介します。多くの場合、何らかのリソースを取得する場合にはユーザの操作とは別に非同期処理が必要になります。そして、それらの結果を画面に反映させる場合には画面が複雑になればなるほど、処理も複雑になりがちです。そこで今回は、ビジネスロジックと画面処理を分けるためのアーキテクチャをいくつか紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

サンプルアプリの概要

 今回、使用するサンプルアプリは図1のようなアプリです。画面は3つありますが、すべて同じ画面であり、また、そのふるまいも同じです。

 ただし、以下のように3つのアーキテクチャを使って実装します。それらの違いについて、アーキテクチャの構造とコード面から違いを見てほしいと思います。

図1:HTTPからJSONデータを取得し表示するサンプルアプリの画面
図1:HTTPからJSONデータを取得し表示するサンプルアプリの画面
  1. Stateのみを用いる方法
  2. 変更(イベント)通知(ProviderとChangeNotifier/Consumer)を用いる方法
  3. BLoCパターン(ProviderとStreamController/StreamBuilder)を用いる方法

Stateのみを用いる方法

 この方法はアーキテクチャと呼べるかわかりませんが、最も基本となる知識のみを使って実装する方法です。後で紹介する他の2つの方法と比べて、どこが変わるかを知っていただくために最初に紹介します。

 また、このコードの構造を簡易的に示したのが図2です。

図2:Stateのみを用いた場合の構造
図2:Stateのみを用いた場合の構造
[リスト1]Stateのみを用いた実装例(lib/SimpleScreen.dartの抜粋)
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()メソッドになります。

 各画面部品を表示する実装はこの後紹介する方法でも、ほぼ同様のため、このコードと違うところに着目して、他のコードを見るようにしてください。

次のページ
変更(イベント)通知(ProviderとChangeNotifier/Consumer)を用いる方法

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Flutterで始めるモバイルアプリ開発連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18105 2023/08/21 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング