Dart/Flutter連載の4記事目は、Flutterでの画面レイアウトの入門です。
Flutterを触ったことがない方にも「こんな感じで画面が作れるんだな」というイメージがつくようお伝えできればと思います。また、私がつまずいたWidgetのサイズ調整についても記載します。
Scaffold Widgetでベースとなるレイアウト構造を作成
FlutterのUIは、Widgetと呼ばれる部品を組み合わせて構築します。
画面のベースとなるレイアウト構造は、Scaffold Widgetで定義します。Scaffold Widgetには、appBar, body, botomNavigationBar等のプロパティが用意されており、それぞれに各Widgetを配置することでページ上部のAppBarや下部のナビゲーションバー等を簡単に配置できます。ページのメインコンテンツはbodyに定義します。
FAB(フローティングアクションボタン)と呼ばれる、スマホアプリのUIでよく見かける画面上の浮いているようなボタンについても、Scaffoldプロパティに用意されており、配置位置も簡単に定義できます。
1 | Scaffold( |

Widgetの配置に必須のColumn, Row Widget
Widgetを垂直に並べたいときは、Column Widget, 水平に並べたいときはRow Widgetを用いて配置します。メイン軸方向にどのように配置するかをmainAxisAlignment
プロパティで定義することができ、Column Widgetの場合は垂直方向、Row Widgetの場合は水平方向を指します。
1 | body: Column( |

意外と難しいWidgetのサイズ調整
Widgetのサイズは、直接的には指定せずにFlutterの自動調整に任せる場合も多く、異なる画面サイズにも柔軟に対応できて便利です。ただし明示的に指定していないため、意図しないサイズになってしまい戸惑うことがよくありました。
Widgetは、親Widgetから与えられた幅・高さの最大値と最小値をもとに、自身のサイズを決定します。
https://flutter.dev/docs/development/ui/layout/constraints
ただし、与えられた最大値・最小値からどのようにサイズを決定するかは、Widgetによって異なり、またWidgetの親子関係によっても変わってきます。各Widgetのサイズ決定については私自身まだ理解できていない部分が多くありますが、一例としてContainer Widgetのサイズの挙動について紹介します。Container Widgetは明示的にサイズを指定することも可能ですが、今回は直接的な指定は行わない場合のサイズの挙動・調整について記載します。
Container Widgetのサイズ
Container Widgetのサイズは、子要素の有無で違ってきます。
1 | // 子要素がない場合は可能な限り最大サイズになる |

Column Widgetでラップした際のContainer Widgetのサイズ
単純にColumn Widgetでラップした場合は、最小限のサイズになります。
さらにContainer WidgetをExpanded Widgetでラップすると、メイン軸方向(Columnの場合は垂直方向)にサイズを拡張してくれます。また、Expanded WidgetのFlex
プロパティで、各Widgetを均等な大きさにしたり大きさの割合を指定できます。
垂直方向へのサイズの拡張は、Column WidgetのCrossAxisAlignment
プロパティにCrossAxisAlignment.stretchを指定することで可能になります。
1 | // Column Widgetのみ |

おわりに
Flutterの画面構築は細かく位置やサイズを指定しなくても、それらしいUIが作れるため、かなりスピーディーに開発ができる印象です。その反面、Widgetのサイズ決定の理解に難しさも感じています。
今回はレイアウト作成の導入的な記事となりましたが、より理解が進んだ後にWidgetのサイズ決定についても記事化できればと思います。
Dart/Flutter連載の4記事目でした。明日は真野さんのFlutterで技術ブログRSSリーダーの記事です。