CodeZine(コードジン)

特集ページ一覧

Flutterの基本的なレイアウトの考え方・仕組みを学ぼう

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2021/09/07 11:00

 UIアプリケーションの開発で最もなやむのが、伝えたい情報や使ってほしい機能をどのように利用者に伝えるかということです。その中で、レイアウトは非常に重要な要素のひとつです。同じ情報であっても見せ方によって伝わりやすさ、効果が異なるからです。また、レイアウトの構成は、プログラムの構造にも影響を与えます。例えば、レイアウトを分ける場合には同時にソースコードも分けるということがあります。同じレイアウトを実現するにも、さまざまな方法があるのです。本記事では、そのようなレイアウトのしくみについて紹介します。Flutterの基本的なレイアウトの考え方をつかんでもらえればと思います。

目次

レイアウトウィジェットの役割

 Flutterでは、レイアウトには大きく分けて以下の2種類があります。

  • 1つのウィジェットを配置するためのレイアウト(Single-child layout Widgets)
  • 複数ウィジェットを配置するためのレイアウト(Multi-child layout Widgets)

 複数の子ウィジェットを管理できるレイアウトだけあれば、1つだけのウィジェットは管理できると思う方もいると思います。機能的な面で考えれば、その考えは正しいでしょう。

 しかし、あえて分けることで図1のような役割としてきく分けることができ、わかりやすくなります。

図1:Single-childとMulti-child layout Widgetsの役割の違い
図1:Single-childとMulti-child layout Widgetsの役割の違い

 例えば、単一ウィジェット用のレイアウトでは配置だけではなく、ボーダーの管理や影をつける等のデコレーション効果を担います。一方で複数ウィジェット用のレイアウトでは、配置とその振る舞いに専念するというようなことが可能になります。

 実際に利用する際には、必ずしもこのような明確な使い分けができない場合もあります。しかし、おおよその役割が分かれていることで、複雑なレイアウトの場合にも直感的なコードが書きやすくなるというメリットがあります。

Container(単一レイアウトの基本形)

 単一のウィジェットのためのレイアウトには、主に表1のようなものがあります。Containerウィジェットは、これらのウィジェットの基本となるウィジェットです。

表1:主なSingle-child layout Widgets
ウィジェット名 説明
Container Single-child layout Widgetの基本ウィジェット
Align 位置揃えをするためのウィジェット
AspectRatio サイズを比率で決定するためのウィジェット
Baseline テキストなどのベースラインによる位置揃えをするためのウィジェット
Center 中央に位置揃えをするためのウィジェット
ConstrainedBox 子ウィジェットに制限を強制するためのウィジェット
Expanded サイズを自動的に親ウィジェットに合わせて広げるウィジェット
LimitedBox サイズの最大を制限するためのウィジェット
Offstage 子ウィジェットの表示/非表示を切り替えることができるウィジェット
Padding パディングを指定するウィジェット
SizedBox サイズを指定するウィジェット
SizedOverflowBox 指定する子ウィジェットのサイズを自分自身のサイズを超過して表示することを許可するウィジェット
Transform
子ウィジェットを回転や傾きなどをさせて表示するウィジェット

 Containerでできることが分かれば、他のSingle-childレイアウトウィジェットについて理解する上でも必要なウィジェットです。

 リスト1は、Containerウィジェットのみを使った、基本的なプロパティの役割が分かるようにしたコード例です。

[リスト1]Containerの基本プロパティ(lib/ContainerWidget.dartの抜粋)
Container basicContainer(){
  return Container(
    // (1) サイズと色を指定
    width: 350,
    height: 350,
    color: Colors.green,
    // (2) 子のContainer
    child: Container(
      child: Container( color: Colors.white ),
      // (3) サイズと色を指定
      color: Colors.blue,
      width: 300,
      height: 300,
      // (4) パディングを指定
      padding: EdgeInsets.all(30),
      // (5) マージンを指定
      margin: EdgeInsets.all(50),
      // (6) 配置場所を指定
      alignment: Alignment.center,
    ));
}

 このコードを実行した結果が図2です。ただし、サイズの関係がわかりやすいように説明を加えてあります。

図2:Containerウィジェットを利用したコードの実行結果とその説明
図2:Containerウィジェットを利用したコードの実行結果とその説明

 (1)のようにwidth/heightでサイズを指定します。背景色はcolorプロパティで指定します。このContainerウィジェットは図2での緑色の短形を示しています。(2)のContainerが図2で青色の短形を示し、(3)で同様にwidth/height、colorを指定しています。

 また、パディングとマージンを指定する場合には、(4)や(5)のように指定します。位置を指定する場合には、(6)のようにalignmentを利用します。

 プロパティ名などは違いますが、HTMLでのCSSなどをご存じの方であれば、おおよそイメージはつきやすいのではないかと思います。

パディング/マージン値の指定方法

 通常、パディング値やマージン値を指定する場合には、EdgeInsetsを使って指定します。

 先ほどの例ではパディングやマージンを指定する際に上下左右ですべて同じ値を設定していましたが、リスト2のように個別に指定することも可能です。

[リスト2]値の作成例(lib/ContainerWidget.dartの抜粋)
return Container(
  // (省略)
  child: Container(
    // (省略)
    padding: createPadding(),
    margin: createMargin(),
  ));

// (1) 上下右左を個別に指定する
EdgeInsets createMargin(){
  return EdgeInsets.only(
    left: 10.0,
    top: 20.0,
    right: 30.0,
    bottom: 40.0
  );
}

// (2) 上下(vertical)と左右(horizontal)を指定する
EdgeInsets createPadding(){
  return EdgeInsets.symmetric(
    vertical: 10.0,
    horizontal: 20.0
  );
}

 上下左右を個別に指定する場合には(1)のようにonlyメソッドを使います。そして、上下、または左右で同じ値を指定したければsymmetricメソッドで指定が可能です。これらのメソッドでは必要ない場所の指定はする必要ありません。

飾りをつける

 Containerウィジェットにはボーダーや影などもつけることが可能です。Containerにボーダーや影などの飾りをつける場合には、decorationプロパティを利用します。リスト3は、ボーダーを指定する場合のコード例です。

[リスト3]Containerウィジェットでのボーダー指定例(lib/ContainerWidget.dartの抜粋)
Container borderContainer() {
  return Container(
    child: Text("Hello"),
    // (1) 色の指定はできません
    // color : Colors.white,
    width: 300,
    height: 300,
    alignment: Alignment.center,
    // (2) 飾りをつける
    decoration: BoxDecoration(
      color: Colors.white,
      border: Border.all(width: 15.0, color: Colors.blue)));
  }

 decorationを指定する場合には、(1)のようにcolorプロパティは利用できず、decorationプロパティ側で指定します。ボーダーを指定する場合には、(2)のようにBoxDecorationクラスを利用して作成します。そして、このコードを実行した結果が図3のようになります。

図3:Containerウィジェットへのボーダー指定時の実行結果
図3:Containerウィジェットへのボーダー指定時の実行結果

 続いて、ボーダーに丸みと影をつけるコードがリスト4です。

[リスト4]Containerウィジェットの角を丸めたり、影を付与したりする例(lib/ContainerWidget.dartの抜粋)
return BoxDecoration(
  color: Colors.white,
  border: Border.all(
    width: 5.0,
    color: Colors.blue
  ),
  // (1) 角を丸める効果
  borderRadius: BorderRadius.circular(50),
  // (2) 影をつける効果
  boxShadow: [
    BoxShadow(
      blurRadius: 20
    )
  ]
);

 (1)は、BorderRadiusを使って指定していします。そして、影をつける場合には、(2)のようにboxShadowプロパティにBoxShadowクラスを使うと簡単に作成可能です。このコードを実行した結果が図4のようになります。

図4:Containerウィジェットのボーダーの角丸や影を利用したコードの実行結果
図4:Containerウィジェットのボーダーの角丸や影を利用したコードの実行結果

 このようにContainerウィジェットだけでもさまざまなことが可能です。ただし、プロパティが多くなり多少、コードがわかりにくくなる傾向があります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

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

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。個人紹介主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしど...

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

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

バックナンバー

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

もっと読む

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5