【Flutter/Dart】Container/Row/Column/Stack/Expanded/Flexible/Align/Centerの使い方

この記事からわかること
- Flutter/Dartで使えるレイアウトWidgetの実装方法
- Container/Row/Column/Stack/Expanded/Flexible/Align/Centerの使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- Mac M1:Sonoma 14.6.1
FlutterのレイアウトWidget
Flutterではレイアウト構成できるWidgetが色々用意されています。今回はそれぞれの特徴や使い方などをまとめていきたいと思います。
- Container・・・基本的なレイアウト、スタイリング、サイズ設定
- Row / Column・・・横方向 / 縦方向にWidgetを並べる
- Stack・・・子Widgetを重ねて表示
- Expanded / Flexible・・・親Widget内でのスペース
- Align / Center・・・子Widgetの位置を指定して配置
Container

「Container」は基本的なレイアウトを構築するためのWidgetです。サイズや余白、背景色など様々な項目をカスタマイズすることが可能でchild
に子供となるWidgetを渡します。
Container(
width: 100, // 横幅
height: 100, // 高さ
padding: EdgeInsets.all(20), // 内部余白
margin: EdgeInsets.symmetric(vertical: 10), // 外部余白
color: Colors.black, // 背景色
child: Text(
'Container',
style: TextStyle(color: Colors.white),
),
)
BoxDecorationでグラデーションや角丸、影など
背景色のグラデーションや角丸、ドロップシャドウなどをしたい場合はdecoration
にBoxDecoration
を活用することでカスタマイズ可能です。
Container(
width: 100,
height: 100,
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.red, Colors.orange], // グラデーション色
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Text(
'グラデーション',
style: TextStyle(color: Colors.white),
),
)
角丸 & 影
Container(
width: 100,
height: 100,
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.orange,
// 角丸
borderRadius: BorderRadius.circular(20),
boxShadow: [
// 影
BoxShadow(
color: Colors.black.withOpacity(0.3),
blurRadius: 10,
spreadRadius: 3,
offset: Offset(4, 4),
),
],
),
child: Text(
'角丸',
style: TextStyle(color: Colors.white)
),
)
子Widgetの配置(Alignment)を制御する
子Widgetの配置(Alignment)を制御するにはalignment
にAlignment
型で制御したい位置を指定します。
Container(
width: 200,
height: 100,
color: Colors.yellow,
alignment: Alignment.center, // 中央配置
child: Text('中央配置'),
)
- Alignment.topLeft → 左上
- Alignment.topRight → 右上
- Alignment.bottomLeft → 左下
- Alignment.bottomRight → 右下
Row / Column

「Row / Column」は横方向 / 縦方向に子Widgetを並べるレイアウトWidgetです。子供にはchildren
で[Widget]
形式で複数のWidgetを渡すことが可能で、Rowなら横方向に、Columnなら縦方向に整列します。
Row
Row(
// 横方向の配置
mainAxisAlignment: MainAxisAlignment.center,
// 縦方向の配置
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.home),
Icon(Icons.star),
Icon(Icons.settings),
],
)
Column
Column(
// 縦方向の配置
mainAxisAlignment: MainAxisAlignment.start,
// 横方向の配置
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.home),
Icon(Icons.star),
Icon(Icons.settings),
],
)
mainAxisAlignment
はRowなら横、Columnなら縦方向にcrossAxisAlignment
はRowなら縦、Columnなら横方向の配置位置を制御しています。
Stack

「Stack」は子Widgetを重ねて表示するレイアウトWidgetです。重なる順番はリストの順番に比例しており後に指定しているWidgetが上に重なっていきます。またPositioned
を使用することで座標で位置を指定することも可能です。
Stack(
children: <Widget>[
Container(width: 200, height: 200, color: Colors.blue),
Positioned(
top: 20,
left: 20,
child: Icon(Icons.star, size: 50),
),
],
)
Expanded / Flexible

公式リファレンス:Expanded
公式リファレンス:Flexible
「Expanded / Flexible」は親Widgetの領域を占めるように広がるレイアウトWidgetです。Expanded
では広がれる最大だけ広がりFlexible
ではflex
に指定した値に応じた比率で広がります。
Expanded
Row(
children: <Widget>[
Icon(Icons.home),
Expanded(child: Container(color: Colors.black, height: 50)),
Icon(Icons.star),
],
)
Flexible
Row(
children: <Widget>[
Flexible(
flex: 2,
child: Container(color: Colors.blue, height: 50),
),
Icon(Icons.home),
Flexible(
flex: 1,
child: Container(color: Colors.green, height: 50),
),
],
)
Spacer / SizedBox
「Spacer / SizedBox」は余白用のUI Widgetです。Spacer
はフレキシブルな余白Viewを作成し、SizedBox
では固定値の余白Viewを実装します。
Row(
children: <Widget>[
Spacer(),
Flexible(
flex: 2,
child: Container(color: Colors.blue, height: 50),
),
SizedBox(height: 20),
Flexible(
flex: 1,
child: Container(color: Colors.green, height: 50),
),
Spacer(),
],
)
Align / Center
公式リファレンス:Align
公式リファレンス:Center
「Align / Center」は子Widgetの位置を指定できるレイアウトWidgetです。Align
はAlignment
で指定した位置に、Center
は中心に配置されます。
Align(
alignment: Alignment.topRight, // 右上に配置
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
)
Center(
child: Text('Centered Text'),
)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。