これまで見てきたとおり、mainAxisAlignmentプロパティとcrossAxisAlignmentプロパティは、RowとColumnが両方の軸に沿ってウィジェットを配置する方法を決定します。
RowとColumnは最初に大きさが固定されているウィジェットを配置します。Fixed size widgetsは配置された後に自身のサイズを再設定できないので、inflexibleと見なされます。
Flexibleウィジェットでラップしたウィジェットは、サイズを再設定できるようになります。Flexibleウィジェットがあるウィジェットをラップすると、そのウィジェットはFlexibleウィジェットの子ウィジェットとなり、flexibleと見なされます。inflexibleウィジェットが配置された後、その(Flexibleウィジェットでラップされた)ウィジェットは、flexプロパティとfitプロパティにしたがってサイズを再設定されます。
flexプロパティ
各Flexibleウィジェットが受け取る残りの合計スペースの割合を決定する前に、他の(Flexibleウィジェットの)flexプロパティと比較します。
fitプロパティ
フレキシブルウィジェットがその余分なスペースをすべて埋めるかどうかを決定します。
Laying out widgets in rows and columns is straightfoward, if those widgets have a fixed size.
ウィジェットのサイズが固定されている場合、ウィジェットを行と列に配置するのは簡単です。
But what if you want a size that’s relative to their parent?
しかし、親に相対的なサイズが必要な場合はどうでしょうか。
and what if you want to adjust those widgets when their parent’s size changes?
親のサイズが変更されたときにこれらのウィジェットを調整したい場合はどうなりますか?
this is trivial to do using the Flexible widget.
これは、Flexibleウィジェットを使用して行うのは簡単です。
Using Flexible is easy.
フレキシブルの使用は簡単です。
Wrap each child in the row or column into Flexible,and give it a flex value.
RowまたはColumnのそれぞれの子ウィジェットをFlexibleでラップし、flexフィールドに値を指定します。
The sum of all the flex values determines how much space each Flexible will use.
すべてのflex値の合計によって、各Flexibleが使用するスペースの量が決まります。
So here, the first child takes up a third of the column,the second takes up a half,and the final takes up 1/6.
したがって、ここでは、最初の子が列の1/3を占め、2番目の子が1/2を占め、最後の子が1/6を占めます。
you can also tell Flexible how strict its sizing should be by specifying a fit,which can be either loose or tight.
また、fitプロパティを指定することで、サイズをどの程度厳密にする必要があるかをFlexibleウィジェットに伝えることができます。
fitプロパティがとりうる値はFlexFit.looseかFlexFit.tightです。
here, by making the fit loose,the container’s preferred size takes precedence.
ここでは、フィットをlooseにすることにより、コンテナの優先サイズが優先されます。
You can also mix and match Flexibles with fixed size widgets.
Flexibleウィジェットをサイズが固定されたウィジェットと組み合わせて使うこともできます。
sample1-1
//sample1-1 //main.dart import 'package:flutter/material.dart'; void main(){ runApp(MyApp(),); } class MyApp extends StatelessWidget{ @override Widget build(BuildContext context){ return MaterialApp( home:Scaffold( appBar:AppBar(), body:MyWidget(), ), ); } } class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: <Widget>[ Flexible( flex: 4, fit:FlexFit.tight, child: Container( height:20, color: Colors.pinkAccent[100], ) ), Flexible( flex: 1, child: Container( color: Colors.pinkAccent[200], ) ), Flexible( flex: 2, child: Container( color: Colors.pinkAccent[700], ) ), ], ); } }
sample1-1(result)
sample1-2(上のウィジェットの高さを指定する)
import 'package:flutter/material.dart'; void main(){ runApp(MyApp(),); } class MyApp extends StatelessWidget{ @override Widget build(BuildContext context){ return MaterialApp( home:Scaffold( appBar:AppBar(), body:MyWidget(), ), ); } } class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: <Widget>[ Flexible( flex: 4, child: Container( height:100, //←高さを指定する。高さを変えてみる。 color: Colors.pinkAccent[100], ) ), Flexible( flex: 1, child: Container( color: Colors.pinkAccent[200], ) ), Flexible( flex: 2, child: Container( color: Colors.pinkAccent[700], ) ), ], ); } }
sample1-2(result)
一番目のウィジェットの高さが100になった。
sample1-3(高さを変えてみる)
height:200, height:300, height:400,
Flexibleウィジェットには
flexプロパティ
fitプロパティ
があり、sample1-2ではflexプロパティは指定しているが、fitプロパティは指定していない。
Flexibleウィジェットのflexプロパティは、nullあるいは0と指定すると、子ウィジェット(今回はContainerウィジェット)はinflexibleと見なされ、Containerウィジェット自身のサイズが使われる。
flexプロパティを0以外に指定した場合だが、
sample1-1では三つのFlexibleウィジェットのflexプロパティを4:1:2と指定しているので、それぞれの高さが利用可能領域の4/7,1/7,2/7と決定される。
Flexibleウィジェットのfitプロパティを指定しない場合デフォルトで
FlexFit.loose
という値が自動的に指定される。fitプロパティがFlexFit.looseの場合の挙動がsample1-3、ということ。fitプロパティがFlexFit.looseの場合、子ウィジェット(この場合Containerウィジェット)が利用可能な領域より小さいサイズが認められる。
この場合の「利用可能な領域」とは、全画面からappBarの高さを除いた高さの4/7。Containerの高さが4/7より小さい場合指定された高さになる。
sample1-4(fitプロパティをFlexFit.tightに指定)
import 'package:flutter/material.dart'; void main(){ runApp(MyApp(),); } class MyApp extends StatelessWidget{ @override Widget build(BuildContext context){ return MaterialApp( home:Scaffold( appBar:AppBar(), body:MyWidget(), ), ); } } class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: <Widget>[ Flexible( flex: 4, fit:FlexFit.tight, //←fitプロパティをFlexFit.tightに指定した。 child: Container( height:200, //←高さを変えてみる。 color: Colors.pinkAccent[100], ) ), Flexible( flex: 1, child: Container( color: Colors.pinkAccent[200], ) ), Flexible( flex: 2, child: Container( color: Colors.pinkAccent[700], ) ), ], ); } }
sample1-4(result)
height:200, height:300, height:400,
fitプロパティをFlexFit.tightに指定した場合。
子ウィジェット(Containerウィジェット)のサイズに関わらず、Flexibleは利用可能領域(全画面からappBarの高さを除いた高さの4/7)全てを使うことを子ウィジェットに強制する。
参考
https://flutter.dev/docs/codelabs/layout-basics
https://flutter.dev/docs/codelabs/layout-basics#flexible-widget
https://www.woolha.com/tutorials/flutter-using-flexible-widget-examples