詳細画面の作成
続いて、詳細画面を作成していきます。同じようにレイアウト構成を決め、その構成に合わせてコードを作成していきます。
詳細画面のレイアウト構成
詳細画面を作成するレイアウト構成を示したものが図5です。こちらは、一覧画面に比べれば非常にシンプルなものになります。ただし、先ほどの一覧画面の重ねて表示する必要があります。
このような構成の場合には、画面遷移で紹介したようにNavigatorを使って別画面として作ることも紹介しました。しかし、今回はレイアウトウィジェットの使い方を説明するために同じ画面の中に重ねて表示する形で作っています。
実際のアプリケーション作成時には、どちらの方法で作った方がよいのだろうかと悩む場合もあります。実際にどちらでも可能ですが、それぞれ特徴が変わってきます。
例えば、詳細画面を閉じても一覧画面のスクロール位置といった利用者が操作した状態をできるだけ維持したい、または、意図的に戻るボタン、進むボタンではたどりつけない画面として表示させたい場合は、画面を重ねて作るような仕組みのほうが簡単です。
画面の上に別の画面を重ねる方法
画面または部品を重ねて表示する場合には、Stackレイアウトを使うと可能です。似た名前のレイアウトにIndexedStackがありますが、こちらは指定した1つの画面または部品になります。
リスト4がStackウィジェットを使ったコード例です。
class _MainPageWidget extends State{ bool _isSelectedItem = false; // 省略 @override Widget build(BuildContext context) { // (1)重ねて表示する return Stack( children: [ CouponListView(openDetail), // (2) 表示する場合のみ if (_isSelectedItem) CouponDetail(closeDetail) ], ); } }
こちらは、MaterialAppのhomeウィジェットのクラスであるMainPageWidgetのコードになります。そのため、正確には詳細ページのレイアウトではありません。
(1)Stackは表示する下から上に向かって表示される順にウィジェットをchildrenに複数指定すればよいだけです。今回、表示する詳細画面は、ボタンを押されたときだけに表示するようにするので、(2)のように表示するもしくは表示しないの制御を入れます。
Columnのサイズを子のサイズに合わせる
詳細画面を作成する際のレイアウト構成は簡単なのですが、やはり何点か思ったように表示されない場所を見つけることでしょう。その1つが、Columnが画面サイズと同じになってしまい、一覧画面が表示されないという点です。
これは、Columnが親ウィジェットのサイズ、つまり、今回は画面サイズと同じサイズの自動的に調整されることです。この調整方法を変更するコードがリスト5です。
// コンテンツの中身 Widget mainContent(){ return Column( // (1) 表示するサイズを最小にする mainAxisSize: MainAxisSize.min, children: [ Image.asset('assets/images/c_img.jpg'), mainCenterContent(), mainBottomContent(), ], ); }
サイズにあわせ方を変更するには、(1)のようにmainAxisSizeプロパティを指定します。MainAxisSizeにはmax/minの固定値を持っていて、今回は子ウィジェットにあわせるのでminを指定します。
空白スペースを使ったサイズの調整
続いて、Row(Columnを使った場合でも同様)で、余白(スペーサー)を使った配置方法を紹介します。中央に1つのボタンウィジェットを配置するだけなので、位置ぞろえでも可能です。
しかし、位置ぞろえではなくてスペーサーを使うと、より直感的な配置ができる場合もあります。例えば、1:2:1のような割合の幅で中央に置きたい場合です。両脇をスペーサーとして、中央をボタンとして割合で指定が可能です。そのようなコードがリスト6です。
Row( children: [ // (1) スペーサーを配置 Spacer( flex: 1, ), // (2) ボタンを配置 Expanded( flex: 2, child: ElevatedButton( // :省略 ) ), // (3) スペーサーを配置 Spacer( flex: 1, ) ] )
(1)でSpacerウィジェットを配置します。flexプロパティがあるのでここで全体の中での比率を指定します。
そして、(2)でこれまで何回か紹介したExpandedウィジェットを配置します。このウィジェットはこれまで、できるだけ広げるように使ってきましたが、flexプロパティでその比率を指定することができます。
また、最後にも同様に(3)Spacerウィジェットを配置します。SpacerとExpandedウィジェットを使えば、このように比率に応じた配置が可能です。ちょうど、HTML/CSSなどでは、配置調整をするためだけにdivタグをおいてスペースを管理する場合と似ています。このように、HTML/CSSになれていれば、Flutterでも同じように考えることができるシーンが多々あります。
まとめ
Flutterには非常に似たレイアウトが多くあります。そのため、よく理解していれば、さまざまな方法で実現できるという利点がある一方、最初はどれをどのように使えばよいかむしろ悩んでしまうということがあります。
また、リファレンスを見ても実際にどのようになるのかがわからないということも多々あります。そして、すべてのウィジェットを実際に使いながら覚えていくにはプロパティもしくはウィジェットクラスがありすぎます。
そのため筆者は、できるだけ基本的なレイアウトだけで作成していき、何か問題が生じた、もしくは思ったレイアウトが実現できない問題が生じたい場合に、これまで使ったことがないプロパティやレイアウトクラスを調べていきます。
しかし、それでは便利なウィジェットを知らずに、大変な思いをしたまま開発し続けてしまうかもしれません。Flutterでは、リファレンス内にYouTubeのビデオが含まれています。
こちらは、Wiget of the Weekというシリーズで公開されているので、そちらを眺めながら気になったものを使っていく方法がよいと思っています。