🙆

【Flutter】Widgetレイアウトの超基本!

2023/04/24に公開

Widgetのレイアウトを実装できるContainer, Row, Colomn, Stack, SizedBox, Wrap, Expanded, Flexible, LayoutBuilder, Center, Align, Paddingについてそれぞれ簡単な実装例ともに紹介しています。

参考

Container

Containerは、Widgetの外観を指定するために使用される基本的なものの1つです。 Containerは、背景色、境界線、パディング、マージン、幅、高さなどのプロパティを設定できます。例えば、以下のようなコードで、Containerの背景色を赤、幅を200ピクセル、高さを100ピクセルに設定できます。

Container(
  width: 200,
  height: 100,
  color: Colors.red,
)

Row

Rowは、水平方向にWidgetを配置するために使用されます。Rowは、子Widgetを横に並べて表示し、自動的にWidgetの幅を調整します。例えば、以下のようなコードで、Row内に3つのContainerを横並びに配置できます。

Row(
  children: [
    Container(
      width: 50,
      height: 50,
      color: Colors.red,
    ),
    Container(
      width: 50,
      height: 50,
      color: Colors.green,
    ),
    Container(
      width: 50,
      height: 50,
      color: Colors.blue,
    ),
  ],
)

Column

Columnは、垂直方向にWidgetを配置するために使用されます。Columnは、子Widgetを縦に並べて表示し、自動的にWidgetの高さを調整します。例えば、以下のようなコードで、Column内に3つのContainerを縦に配置できます。

Column(
  children: [
    Container(
      width: 50,
      height: 50,
      color: Colors.red,
    ),
    Container(
      width: 50,
      height: 50,
      color: Colors.green,
    ),
    Container(
      width: 50,
      height: 50,
      color: Colors.blue,
    ),
  ],
)

Stack

Stackは、複数の子Widgetを重ねて表示することができます。子Widgetは、親Widget(Stack自体)の左上隅を基準に、上から下に重ねられます。Stack内に配置されたWidgetは、指定された位置に重なり合い、一番上にあるものが最上位に表示されます。

Stack(
  children: [
    Container(color: Colors.red, width: 100, height: 100),
    Container(color: Colors.green, width: 80, height: 80),
    Container(color: Colors.blue, width: 60, height: 60),
  ],
)

SizedBox

SizedBoxは、特定の幅と高さを持つボックスを作成するWidgetです。他のWidgetと一緒に使用することで、Widget間のスペースを確保したり、Widgetのサイズを制御することができます。

Column(
  children: [
    Container(
      width: 50,
      height: 50,
      color: Colors.red,
    ),
    SizedBox(height: 100),
    Container(
      width: 50,
      height: 50,
      color: Colors.green,
    ),
    SizedBox(height: 100),
    Container(
      width: 50,
      height: 50,
      color: Colors.blue,
    ),
  ],
)

Wrap

Wrapは、子Widgetを横に並べ、使用可能なスペースを超えた場合に自動的に次の行に折り返すものです。これにより、レイアウトが自動的に適応され、コンテンツが画面内に収まるようになります。Wrapは、子WidgetにDirectionalityWidgetが必要な場合があります。

Wrap(
  spacing: 8, // ウィジェット間のスペース
  runSpacing: 4, // 行間のスペース
  children: [
    Chip(label: Text("Flutter")),
    Chip(label: Text("Dart")),
    Chip(label: Text("Android")),
    Chip(label: Text("iOS")),
    Chip(label: Text("Web")),
    Chip(label: Text("Linux")),
    Chip(label: Text("MacOS")),
  ],
)

Expanded

Expandedは、Flexとともに使用され、Flex内で利用可能な余剩の空間を均等に分割することができます。主にColumnやRowなどのFlexベースのレイアウトで子ウィジェット間の空間を調整する際に使用されます。

Row(
  children: [
    Expanded(
      child: Container(color: Colors.red, height: 100),
    ),
    Expanded(
      child: Container(color: Colors.green, height: 100),
    ),
  ],
)

Flexible

FlexibleもExpandedと同様にFlexとともに使用されますが、より柔軟に空間の調整ができる点が異なります。Flexibleには"flex"というプロパティがあり、その値に応じてウィジェット間の空間が分割されます。デフォルトではflexの値は1です。

Row(
  children: [
    Flexible(
      flex: 2,
      child: Container(color: Colors.red, height: 100),
    ),
    Flexible(
      flex: 1,
      child: Container(color: Colors.green, height: 100),
    ),
  ],
)

LαyoutBuilder

LayoutBuilderは、親Widgetの制約に基づいて子Widgetを動的に構築する際に使用されます。LayoutBuilderは、BuildContextと制約を引数として受け取るBuilder関数を提供します。これにより、Widgetは自身の親の制約に応じてサイズや位置を変更できます。

LayoutBuilder(
  builder: (BuildContext context, BoxConstraints constraints) {
    // 画面の幅に応じて背景色を変更
    Color backgroundColor;
    if (constraints.maxWidth < 392) {
      backgroundColor = Colors.red;
    } else if (constraints.maxWidth < 392.8) {
      backgroundColor = Colors.green;
    } else {
      backgroundColor = Colors.blue;
    }

    return Container(
      color: backgroundColor,
      width: constraints.maxWidth,
      height: constraints.maxHeight,
      child: Center(
	child: Text(
	  '画面の幅: ${constraints.maxWidth.toStringAsFixed(2)}',
	  style: TextStyle(fontSize: 24, color: Colors.white),
	),
      ),
    );
  },
),

Iphone 14 Pro (Width)

Pixel 5

Center

Centerは、子Widgetを親Widgetの中心に配置するために使用されます。Centerは、縦横両方向で子Widgetを中央に配置します。

Center(
  child: Text('Hello, World!'),
)

Align

Alignは、子Widgetを親Widget内の特定の位置に配置するために使用されます。alignmentプロパティを使用して、配置する位置を指定できます。

Align(
  alignment: Alignment.topLeft,
  child: Text('Hello, World!'),
)

Padding

Paddingは、子Widgetとその周囲の空間を制御するために使用されます。Paddingは、EdgeInsetsを使用して指定されます。EdgeInsetsは、上下左右のオフセットを表します。

Padding(
  padding: EdgeInsets.all(16.0),
  child: Text('Hello, World!'),
)

Discussion