LoginSignup
15
4

More than 1 year has passed since last update.

【Flutterレイアウト】Flex、Row、Column、Wrap、Stackについて

Last updated at Posted at 2022-05-08

Flutterレイアウトシリーズのその他の記事

この記事はFlutterの複数子ウェジェットを持つレイアウトウェジェットを理解するため書いたものです。

※本記事は下記のZenn本にまとめました。

Flex

RowとColumnはFlexを継承していて、directionはAxis.horizontalとAxis.verticalのウェジェットである、すなわち、RowとColumnはFlexのdirection属性を固定したもの。

コンストラクター

  Flex({
    Key? key,
    required this.direction,
    this.mainAxisAlignment = MainAxisAlignment.start,
    this.mainAxisSize = MainAxisSize.max,
    this.crossAxisAlignment = CrossAxisAlignment.center,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be
    this.clipBehavior = Clip.none,
    List<Widget> children = const <Widget>[],
  }) : assert(direction != null),
       assert(mainAxisAlignment != null),
       assert(mainAxisSize != null),
       assert(crossAxisAlignment != null),
       assert(verticalDirection != null),
       assert(crossAxisAlignment != CrossAxisAlignment.baseline || textBaseline != null, 'textBaseline is required if you specify the crossAxisAlignment with CrossAxisAlignment.baseline'),
       assert(clipBehavior != null),
       super(key: key, children: children);

属性

属性 説明
direction 主軸の方向
mainAxisAlignment メイン軸/主軸に対する整列
mainAxisSize 主軸のサイズ
crossAxisAlignment クロス軸/交差軸の整列
textDirection 文字列の方向
verticalDirection 垂直方向
textBaseline 文字列のベースライン

direction

  • Axis.horizontal
    子ウェジェットたちの並び方向を水平にする。Axis.horizontalに定義した時はRowと同じものと見られる。
  • Axis.vertical
    子ウェジェットたちの並び方向を垂直にする。Axis.verticalに定義した時はColumnと同じものと見られる。

mainAxisAlignment

メイン軸/主軸に対する整列、Rowの場合は横方向の整列、Columは縦方向整列

/// How the children should be placed along the main axis in a flex layout.
///
/// See also:
///
///  * [Column], [Row], and [Flex], the flex widgets.
///  * [RenderFlex], the flex render object.
enum MainAxisAlignment {
  • MainAxisAlignment.start
    始点から整列
  • MainAxisAlignment.end
    末尾から整列
  • MainAxisAlignment.center
    センターから整列
  • MainAxisAlignment.spaceBetween
    両端を揃える。つまり、最初の子が左側にあり、最後の子が右側にあり、残りの子が中央に均等に分散される。
  • MainAxisAlignment.spaceAround
    各子の左右の間隔を等しくする、つまりmarginは等しい。
  • MainAxisAlignment.spaceEvenly
    各子は均等に分散される。つまり、幅は同じ。

Rowを例として確認します。

MainAxisAlignment.start MainAxisAlignment.end MainAxisAlignment.center
MainAxisAlignment.spaceBetween MainAxisAlignment.spaceAround MainAxisAlignment.spaceEvenly

mainAxisSize

主軸のサイズ、デフォルトはMainAxisSize.max
制約条件による機能する、親の制約は緩い場合のみ機能する。
下記のソースコードで区別を確認しよう、Alignで制約を緩める(詳細は前の記事を確認しよう)
MainAxisSize.maxは制約サイズ最大に伸ばせる

return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.lightGreen,
          child: Align(
            child: Container(
              color: Colors.white,
              child: Row(
                mainAxisSize: MainAxisSize.max,
                children: [
                  SizedBox(
                    width: 100,
                    height: 100,
                    child: Container(
                      color: Colors.yellow,
                    ),
                  ),
                  SizedBox(
                    width: 100,
                    height: 200,
                    child: Container(
                      color: Colors.green,
                    ),
                  ),
                  SizedBox(
                    width: 100,
                    height: 100,
                    child: Container(
                      color: Colors.red,
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
MainAxisSize.max MainAxisSize.min

verticalDirection

子ウェジェットの整列順序、デフォルトはdown
down:topからbottom
up:bottomからtop

crossAxisAlignment

クロス軸/交差軸の整列,Rowの場合は縦方向の整列、Columは横方向の整列

/// How the children should be placed along the cross axis in a flex layout.
///
/// See also:
///
///  * [Column], [Row], and [Flex], the flex widgets.
///  * [RenderFlex], the flex render object.
enum CrossAxisAlignment {
  /// Place the children with their start edge aligned with the start side of
  /// the cross axis.
  • CrossAxisAlignment.start
    Rowは縦方向の上から整列
  • CrossAxisAlignment.end
    Rowは縦方向の下から整列
  • CrossAxisAlignment.center
    Rowは縦方向の中心より、整列する
  • CrossAxisAlignment.stretch
    子を拡大し、親のレイアウトを埋める
  • CrossAxisAlignment.baseline
    ベースラインを基準に整列する

※クロス軸のcrossAxisAlignment.startとendはverticalDirectionの属性により、影響を与える。verticalDirectionデフォルトはVerticalDirection.downだが、upの時、crossAxisAlignment.startとendの効果は逆になる。
ベースラインを使う際、textBaselineの属性を定義しないといけない

return Scaffold(
      body: SafeArea(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(
              width: 100,
              height: 100,
              child: Container(
                color: Colors.yellow,
              ),
            ),
            SizedBox(
              width: 100,
              height: 200,
              child: Container(
                color: Colors.green,
              ),
            ),
            SizedBox(
              width: 100,
              height: 100,
              child: Container(
                color: Colors.red,
              ),
            )
          ],
        ),
      ),
    );
CrossAxisAlignment.start CrossAxisAlignment.end CrossAxisAlignment.center
CrossAxisAlignment.stretch

Wrap

コンストラクター

class Wrap extends MultiChildRenderObjectWidget {
  /// Creates a wrap layout.
  ///
  /// By default, the wrap layout is horizontal and both the children and the
  /// runs are aligned to the start.
  ///
  /// The [textDirection] argument defaults to the ambient [Directionality], if
  /// any. If there is no ambient directionality, and a text direction is going
  /// to be necessary to decide which direction to lay the children in or to
  /// disambiguate `start` or `end` values for the main or cross axis
  /// directions, the [textDirection] must not be null.
  Wrap({
    Key? key,
    this.direction = Axis.horizontal,
    this.alignment = WrapAlignment.start,
    this.spacing = 0.0,
    this.runAlignment = WrapAlignment.start,
    this.runSpacing = 0.0,
    this.crossAxisAlignment = WrapCrossAlignment.start,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    this.clipBehavior = Clip.none,
    List<Widget> children = const <Widget>[],
  }) : assert(clipBehavior != null), super(key: key, children: children);

属性

属性 説明
direction 主軸の方向
alignment 新しく一行できたとき、主軸に対する整列
spacing 主軸の方向の子ウェジェットの間隔
runAlignment runの整列。行ごとのクロス軸の整列方式
runSpacing runの間隔
crossAxisAlignment 行の子ウェジェットのクロス軸の整列方向
textDirection Flexと同じく、文字列の整列方向
verticalDirection 垂直方向の整列順序
clipBehavior 端を超えてエッジをトリミングする方法

direction

WrapのdirectionデフォルトAxis.horizontal(水平方向)

Axis.horizontal Axis.vertical

alignment

新しく一行できたとき、主軸に対する整列

  • WrapAlignment.start
    始点から整列
  • WrapAlignment.end
    末尾から整列
  • WrapAlignment.center
    センターから整列
  • WrapAlignment.spaceBetween
    両端を揃える。つまり、最初の子が左側にあり、最後の子が右側にあり、残りの子が中央に均等に分散される。
  • WrapAlignment.spaceAround
    各子の左右の間隔を等しくする、つまりmarginは等しい。
  • WrapAlignment.spaceEvenly
    各子は均等に分散される。つまり、幅は同じ。
WrapAlignment.start WrapAlignment.end WrapAlignment.center
WrapAlignment.spaceBetween WrapAlignment.spaceAround WrapAlignment.spaceEvenly

runAlignment

runの整列。行ごとのクロス軸の整列方式。alignmentと同じ列挙型のWrapAlignmentを使われている。

WrapAlignment.start WrapAlignment.end WrapAlignment.center
WrapAlignment.spaceBetween WrapAlignment.spaceAround WrapAlignment.spaceEvenly

crossAxisAlignment

各行の子ウェジェットのクロス軸整列方式

enum WrapCrossAlignment {
  start,
  end,
  center,
}
WrapCrossAlignment.start WrapCrossAlignment.center WrapCrossAlignment.end

textDirection

文字列の整列方向

TextDirection.ltr TextDirection.rtl

verticalDirection

垂直方向の整列順序

VerticalDirection.down VerticalDirection.up

間隔spacingとrunSpacing

spacingは主軸の各子ウェジェットの間隔を定義する、runSpacingは各行の間隔を定義する。

Stack

Stackについて、前の記事で説明したため、ここのリンクをどうぞ!!!

15
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
4