【Flutter】レイアウトの基本
Container
Container
は、HTML の<div>
のように子ウィジェットを内包し、大きさや位置などを調整するためのものです。
Container(
alignment: Alignment.center,
child: Text("はじめてのレイアウト"),
constraints: BoxConstraints.expand(height: 300),
decoration: BoxDecoration(
border: Border.all(color: Colors.blue, width: 5),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 3.0,
spreadRadius: 1.0,
offset: Offset(5, 5),
),
],
color: Colors.blue[50],
),
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
)
Container
は以下のプロパティを持ちます。
プロパティ | 説明 |
---|---|
alignment | 子のウィジェットの位置を設定します。 |
child | 子のウィジェットを設定します。 |
color | 色を設定します。 |
constraints | コンテンツの大きさの制限を設定する。 |
decoration | デザインを設定する。 |
height | コンテンツの高さを設定します。 |
margin | margin を設定します。 |
padding | padding を設定します。 |
width | コンテンツの幅を設定します。 |
プロパティについては以下で補足していきます。
Container
について説明していますが、他のウィジェットのプロパティでも同じ考え方です。
Colors
Colors
は、Flutter で色を設定する際に使用します。
どのような色があるかはこちらを参照してください。
Colors.blue[50]
Colors.red.shade400
Alignment
Alignment
は、ウィジェットの配置位置を指定するのに使用します。
位置は左上を(x, y) = (-1, -1)
、右下を(x, y) = (1, 1)
の座標で考えることができ、以下のコンストラクタによって設定します。
Alignment(-1, -1) //左上
Alignment(0, 0) //中央
Alignment(1, 1) //右下
Alignment(0.2, -0.6)
また特定の位置は、以下のように定数として用意されています。
定数 | 位置(座標) |
---|---|
topLeft | (-1, -1) |
topCenter | (0, -1) |
topRight | (1, -1) |
centerLeft | (-1, 0) |
center | (0, 0) |
centerRight | (1, 0) |
bottomLeft | (-1, 1) |
bottomCenter | (0, 1) |
bottomRight | (1, 1) |
BoxConstraints
BoxConstraints
は、ウィジェットの大きさに関する設定で使用します。
コンストラクタの引数にminHeight
、maxHeight
、minWidth
、maxHeight
を指定することで、幅と高さの最大、最小値を設定します。
引数の指定がない場合は、ウィジェットは親と同じ大きさになります。
BoxConstraints(
minHeight: 200,
maxHeight: 300,
minWidth: 150,
maxWidth: 400,
)
BoxConstraints() //親と同じサイズ
単純に固定サイズを設定する場合は、BoxConstraints.expand
でheight
、width
を指定します。
指定しなかった場合は、親と同じサイズになります。
BoxConstraints.expand(height: 300, width: 200)
BoxConstraints.expand(height: 300) //幅は親と同じ
BoxConstraints.expand(width: 200) //高さは親と同じ
BoxDecoration
BoxDecoration
は、枠線や影などのデザインを設定するために使用します。
注意点として、BoxDecoration
を使用する際はContainer
のcolor
プロパティは設定できません。
代わりにBoxDecoration
のcolor
プロパティを設定します。
Border
Border
によって枠線を設定します。
上下左右それぞれにBorderSide
を指定して、色と太さを設定します。
Border(
top: BorderSide(color: Colors.red, width: 5.0),
right: BorderSide(color: Colors.blue, width: 1.0),
bottom: BorderSide(color: Colors.green, width: 3.0),
left: BorderSide(color: Colors.yellow, width: 10.0)
)
すべて同じデザインの場合は、Border.all()
を使用します。
Border.all(color: Colors.red, width: 5.0)
上下(水平方向)、左右(垂直方向)ごとに設定したい場合は、Border.symmetric()
を使用します。
Border.symmetric(
horizontal: BorderSide(color: Colors.red, width: 5.0),
vertical: BorderSide(color: Colors.blue, width: 1.0),
)
BorderRadius
BorderRadius
は、境界の角を丸めるために使用します。
BorderRadius.circular(10.0)
個別に設定する場合は、BorderRadius.only
を使用します。
ただし、数値でなくRadius
を指定します。
BorderRadius.only(
topLeft: Radius.circular(5),
topRight: Radius.circular(10),
bottomLeft: Radius.circular(1),
bottomRight: Radius.circular(20),
)
BoxShadow
BoxShadow
は、影を設定するために使用します。
BoxShadow(
color: Colors.black26, //影の色
blurRadius: 10.0, //ぼかし具合
spreadRadius: 1.0, //大きさ
offset: Offset(5.0, 5.0), //位置
)
EdgeInsets
EdgeInsets
は、margin
やpadding
を設定するのに使用します。
使用するコンストラクタによってどのように設定するかが異なります。
EdgeInsets.all(10.0) //全方向同じ値
EdgeInsets.fromLTRB(10.0, 5.0, 2.5, 7.5) //全方向個別指定(左上右下)
EdgeInsets.only( //位置指定
bottom: 10.0,
right: 10.0,
)
EdgeInsets.symmetric( //縦横ごとに指定
vertical: 10.0,
horizontal: 20.0,
)
SizedBox
SizedBox
は、指定したサイズのスペースを確保するために使用します。
SizedBox(
child: Text("はじめてのレイアウト"),
height: 200,
width: 300,
)
FractionallySizedBox
SizeBox
は固定値でしたが、FractionallySizeBox
を使用すると親ウィジェットに対する割合でサイズを指定することができます。
FractionallySizedBox(
child: Text("はじめてのレイアウト"),
heightFactor: 0.7, //70%
widthFactor: 0.4, //40%
)
Align
Align
は、Align
の親ウィジェットを基準に、子ウィジェットの位置を指定します。
Align(
alignment: Alignment.center,
child: Text("はじめてのレイアウト"),
)
Center
Center
は、Center
の親ウィジェットの中央になるように子ウィジェット配置します。
Center(
child: Text("はじめてのレイアウト"),
)
FractionalTranslation
FractionalTranslation
は、Offset
を使ってウィジェットの位置を設定します。
FractionalTranslation(
child: Text("はじめてのレイアウト"),
translation: Offset(10.0, 5.0),
)
Padding
Padding
は、余白を設定するためのウィジェットです。
Padding(
child: Text("はじめてのレイアウト"),
padding: EdgeInsets.all(10.0)
)
Row
Row
は、水平方向にウィジェットを並べるために使用します。
HTML でいうところの Flexbox に近いです。
Row(
children: <Widget>[
Container(
color: Colors.blue,
height: 100,
width: 100,
),
Container(
color: Colors.red,
height: 50,
width: 100,
),
Container(
color: Colors.green,
height: 150,
width: 100,
)
],
mainAxisAlignment: MainAxisAligment.start,
crossAxisAlignment: CrossAxisAlignment.center
)
ウィジェットの並べ方については以下より説明します。
MainAxisAlignment
水平方向の位置を設定します。
MainAxisAlignment.start
MainAxisAlignment.center
MainAxisAlignment.end
MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceAround
MainAxisAlignment.spaceEvenly
start
center
end
spaceBetween
spaceAround
spaceEvenly
CrossAxisAlignment
垂直方向の位置を設定します。
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.end
CrossAxisAlignment.stretch
CrossAxisAlignment.baseline
start
center
end
stretch
baseline
Expanded
子ウィジェットをExpanded
で内包することにより、Row
が幅いっぱい広がるように子ウィジェットの幅を設定します。
具体的には、flex
プロパティを指定することにより、幅の比率を指定します。
以下の例であれば、2 つ目の要素(赤)を固定幅としており、残りの幅で 1 つ目の要素(青)と 3 つ目の要素(緑)が 1:2 となるように幅が設定されます。
Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.blue,
height: 100,
),
),
Container(
color: Colors.red,
height: 100,
width: 100,
),
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
height: 100,
),
),
],
)
Column
Column
は、垂直方向にウィジェットを並べるために使用します。
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.blue,
height: 100,
),
Container(
color: Colors.red,
height: 100,
width: 100,
),
Container(
color: Colors.green,
height: 100,
),
],
)
垂直方向になるだけで、考え方はRow
と同じです。
MainAxisAlignment
とCrossAxisAligment
はそれぞれ方向が逆になります。
MainAxis とあるように、MainAxisAlignment
は主方向の配置に関するプロパティです。
よってColumn
では垂直方向の配置に関するプロパティとなります。
CrossAxisAlignment
は直行する方向のプロパティのため、Column
では水平方向のプロパティとなります。
Expanded
も同じように使用できます。
Stack
Stack
は、子のウィジェットを重ねる場合に使用します。
alignment
プロパティにより、子ウィジェットの位置を調整できます。
Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
width: 300,
height: 300,
color: Colors.blue,
),
Container(
width: 200,
height: 200,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.green,
),
],
)
Positioned
Positioned
は、Stack
の子ウィジェットの位置と大きさを設定するために使用します。
指定するプロパティは、位置を表すtop
、right
、bottom
、left
、大きさを表すheight
、width
です。
Stack(
children: <Widget>[
Container(
width: 300,
height: 300,
color: Colors.blue,
),
Positioned(
child: Container(
color: Colors.red,
),
left: 30,
top: 10,
height: 200,
width: 200,
),
Positioned(
child: Container(
color: Colors.green,
),
right: 20,
bottom: 10,
height: 100,
width: 100,
),
],
),
GridView
GridView
は、グリッドレイアウトを行う際に使用します。
Row
とColumn
を組み合わせることでもできますが、1 つのウィジェットで済むためこちらのほうがよい場合もあります。
GridVie
は以下のcount
かetended
を使って設定することが多いです。
count
count
では、列数を指定してグリッドレイアウトを設定します。
GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 10.0,
crossAxisSpacing: 5.0,
padding: EdgeInsets.all(10.0),
children: <Widget>[
Container(
child: Text("One"),
color: Colors.blue[50],
),
Container(
child: Text("Two"),
color: Colors.red[50],
),
Container(
child: Text("Three"),
color: Colors.green[50],
),
Container(
child: Text("Four"),
color: Colors.yellow[50],
),
Container(
child: Text("Five"),
color: Colors.purple[50],
),
],
),
列数はcrossAxisCount
によって設定します。
設定した列数になるように幅と高さが調整されます。
高さは幅と同じ大きさになるように設定されます。
また、子ウィジェットで大きさを設定しても、グリッドの大きさが優先されます。
mainAxisSpacing
とcrossAxisSpacing
は、要素間のスペースを設定するためのプロパティです。
mainAxisSpacing
は行間、crossAxisSpacing
は列間のスペースを設定します。
extent
extent
では、列数ではなく子要素の最大幅を設定します。
GridView.extent(
maxCrossAxisExtent: 150,
mainAxisSpacing: 10.0,
crossAxisSpacing: 5.0,
padding: EdgeInsets.all(10.0),
scrollDirection: Axis.vertical,
children: <Widget>[
Container(
child: Text("One"),
color: Colors.blue[50],
),
Container(
child: Text("Two"),
color: Colors.red[50],
),
Container(
child: Text("Three"),
color: Colors.green[50],
),
Container(
child: Text("Four"),
color: Colors.yellow[50],
),
Container(
child: Text("Five"),
color: Colors.purple[50],
),
],
)
最大幅はmaxCrossAxisExtent
によって設定します。
count
では列数が固定でしたが、extent
ではすべての要素が設定した最大幅内におさまるように幅が調整されます。
そのため、extent
では親の大きさによって列数が変化します。
その他のプロパティについてはcount
と同じです。