SHOEISHA iD

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

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

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

Flutterアプリの画面構成を理解しよう

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


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

BottomNavigationBarウィジェット

 Scaffoldの画面下部にメニューを表示する場合には、BottomNavigationBarウィジェットがよく利用されます。

 BottomNavigationBarウィジェットでは、メニュータブの表示方法には2つのタイプがあります。その違いを示したものが図3です。

図3:ボタン表示タイプの違い
図3:ボタン表示タイプの違い

 (1)はshiftingタイプといい、アクティブなボタン以外はアイコンのみで表示されます。(2)はfixedタイプといいボタンとラベルが常に表示されます。この設定は、typeプロパティで設定するのですが、設定しない場合には、4つ以上のメニューがある場合には、shiftingになり3つ以下であればfixedになります。

 自動で表示方法が変わるところに筆者は少々、びっくりしてしまいました。そのような方は、筆者と同じように必ず指定を明示的にすることをおすすめします。

[リスト2
 BottomNavigationBarの利用例(lib/pages/ScaffoldSample.dartの抜粋)]
bottomNavigationBar: BottomNavigationBar(
  // (1) タイプを指定
  type: BottomNavigationBarType.shifting,
  //  (2) 表示するメニュー
  items: [
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
        label: "ホーム",
        backgroundColor: Colors.black
      ),
      BottomNavigationBarItem(
        icon: Icon(Icons.star),
        label : "マイページ",
        backgroundColor: Colors.black
      ),
      // (省略)
  ],
  // (3) アクティブなタブ
  currentIndex: 2,
  //  (4) タップされた時の処理
  onTap: (int idx){
    //  ボタンがタップされた時の処理
  },
),

 (1)では先ほど紹介したタイプを明示的に指定しています。そして、(2)のように実際に表示するメニューはitemsプロパティにBottomNavigationBarItemウィジェットの配列として指定します。

 また、アクティブな要素は(3)のようにcurrentIndexで指定します。値は0から始まるメニュー配列のインデックス値になります。(4)のようにonTapでタップされたメニューの処理を記述します。

FloatingActionButtonウィジェット

 FloatingActionButtonウィジェットは、丸形のボタンを画面上に配置するためのウィジェットです。例えば、上に戻るボタンや、新規作成ボタンをショートカット的な使い方で配置するボタンとしてよく利用されます。

 デフォルトでは画面右下に表示されますが、ScaffoldのfloatingActionButtonLocationプロパティを指定することで、実際にはさまざまな場所に配置することができます。

 具体的な設置可能な配置場所はAPIドキュメントを参照してください。

 リスト3はScaffoldにFloatingActionButtonを追加する場合の実装例です。

[リスト3] FloatingActionButtonの利用例(lib/pages/ScaffoldSample.dartの抜粋)
floatingActionButton: FloatingActionButton(
  child: Icon(Icons.add),  // (1) 実際に表示するウィジェット
  tooltip: "追加する",      // (2) ツールチップ用の表示文字列
  onPressed: (){           // (3) ボタンが押された時の処理
  },
),

 (1)で実際に表示するウィジェットを指定します。ここではアイコンを表示しています。また、(2)のtooltipでツールチップ用の表示文字列を指定し、(3)のonPressedではボタンが押された時の処理を記述します。

Drawerウィジェット

 Drawerはスワイプで開閉することができるウィジェットです。一般的にはメニューなどを表示します。Drawerは、右から開くDrawerと左から開くDrawerの2種類があります。

 左から開く場合には、Scaffoldのdrawerプロパティを利用し、右から開く場合には、endDrawerプロパティを使用します。

[リスト4] Drawerの利用例(lib/pages/ScaffoldDrawer.dartの抜粋)
drawer: Drawer(
  child: ListView(
    children: [
      DrawerHeader(child: Text("Header")),
      ListTile(
        title: Text("Item 1"),
      ),
      ListTile(
        title: Text("Item 2"),
      )
    ],
  ),
),

 このプログラムを実行した結果が図4です。

図4:Drawerの実行例
図4:Drawerの実行例

Drawerをプログラムからオープンする

 Drawerはスワイプで表示可能ですが、プログラムで開きたい場合があります。これには、リスト4のようにします。

[リスト4] AppBarに配置したボタンからDrawerを開く場合の利用例(lib/pages/ScaffoldDrawer.dartの抜粋)
appBar: AppBar(
  // (1) Builderウィジェットを使う
  leading: Builder(
    builder: (context) => IconButton(
    icon: Icon(Icons.menu),
      onPressed: (){
        // (2) Drawerを開く処理
        Scaffold.of(context).openDrawer();
      })
  ),
  //  ( 省略 )
),

 AppBarウィジェットでleadingプロパティには、(1)のように直接、IconButtonウィジェットを設定せずにBuilderウィジェットを設定しています。これは、onPressedメソッド内でBuildContextを利用したいためです(BuilderContextについては、後で改めます)。そして、(2)のように、openDrawerメソッドを使ってDrawerを開きます。endDrawerに設定しているDrawerを開きたい場合にはopenEndDrawerメソッドを使います。

SnackBarウィジェット

 SnackBarは、画面下部にメッセージを一時的に表示するためのウィジェットです。表示したものは、時間が経過すると自動的に消えます。また、表示する位置は、behaviorプロパティにSnackBarBehaviorの値を指定することで変更できます。

図5:SnackBarの表示位置の違い
図5:SnackBarの表示位置の違い

 また、実際に表示する場合のコードを示したものがリスト5です。

[リスト5] SnackBarウィジェットの利用例(lib/pages/ScaffoldSnackBar.dartの抜粋)
body: Center(
  child: TextButton(
    child: Text("Message"),
      onPressed: (){
        // (1) Snackbarを表示する
        ScaffoldMessenger.of(context).showSnackBar(
          // (2) SnackBarを作成
          SnackBar(
            // (3) 各プロパティの設定
            content: Text("Hello"),
            behavior: SnackBarBehavior.floating,
            duration: Duration(seconds: 5),
            // (省略)
          )
       );
     },
  )
),

 Snackbarを表示する際には、(1)のようにScaffoldMessengerクラスのshowSnackBarメソッドを使います。

 Drawerを表示する場合には、Scaffold.ofメソッドを使いましたが、Snackbarの場合には、ScaffoldMessengerクラスを使います。これによって、Builderウィジェットを使わなくても問題なくなります。(2)でSnackBarを作ります。そして、(3)のように各プロパティを設定します。実際に設定できる項目はSnackBarを参照してください。

BottomSheetウィジェット

 BottomSheetウィジェットは、図6のように画面下部により自由なUIを作りたい場合に使います。SnackBarと似ている部分もありますが、より自由なUIが作れ、メニュー表示などにも利用されます。

 実際に表示する部品は、他のウィジェットのように、既定のウィジェットを使わず自由なウィジェットを利用します。

図6:BottomSheetの表示例
図6:BottomSheetの表示例

 リスト6が実際のBottomSheetを表示する場合の実装例です。

[リスト6] BottomSheetウィジェットの利用例(lib/pages/ScaffoldBottomSheet.dartの抜粋)
onPressed: (){
  // (1) 表示する処理
  Scaffold.of(context).showBottomSheet((BuildContext context) {
    return Container(
      height: 100,
      color: Colors.amber,
      child: Center(
        child: TextButton(
          child: Text("Bottom Sheet"),
          onPressed: (){
            // (2) 閉じる処理
            Navigator.pop(context);
          },
        ),
      ),
    );
  });
}

 実際に表示する場合には、(1)のようにshowBottomSheetメソッドを使って表示するウィジェットを作成します。また、表示したウィジェットを閉じる場合には、(2)のようにNavigator.pop()を使います。これは次回説明しますが、1つ前のページに戻る処理と同じになります。

BuilderとBuildContextとは

 BuilderとBuildContextについては、これまで説明せずに使ってきました。しかし、Scaffold.ofメソッドを使ってうまく動くケースと、正しく動かないケースがあります。それは、多くの場合には指定するBuildContextが間違っているためです。BuildContextとは、ウィジェットを管理しているツリー構造の中で該当のウィジェットを管理するためのクラスで、図7のようなものをイメージしてください。

図7:ウィジェットとBuildContextの関係
図7:ウィジェットとBuildContextの関係

 Scaffold.ofメソッドは、指定したBuildContextインスタンスを使って、親ウィジェットをたどってScaffoldウィジェットを探していく処理です。そのため、Scaffoldを作る際に使ったBuildContextを使う場合には、(1)のようになるため見つかりません。しかし、既存のウィジェットだけを使っていると、ソースコード上どこにもBuildContextが現れません。

 そこで、BuilderウィジェットはBuildContextインスタンスを取得するために利用されます。これで(2)のようにScaffoldウィジェットが見つかるという仕組みです。実際にさまざまな処理を記述していくと、まったく同じコードを記述しているのに動く場合と動かない場合などがあります。その場合には今回の内容を思い出していただけると、問題解決する際にイメージしやすくなります。

まとめ

 今回は、Scaffoldウィジェットで利用できるウィジェットを紹介しました。実際に作成するウィジェットも、どこに表示するかによって変わると思います。従って、今回紹介した部分のどこの部品を作るのかを考える参考にしてもらえればと思います。次回は、作成した各画面をどのように遷移させていくかのページ遷移方法を紹介していきます。

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

  • 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/14064 2022/09/05 20:12

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング