Flexibleは、Flexコンテナ内で子要素が利用可能なスペースをどのように占有するかを制御するFlutterウィジェットです。Expandedとは異なり、Flexibleは子に割り当てられた領域全体を埋めることを強制しません — 子ウィジェットは小さくてもよく、残りのスペースは空のままです。公式のFlutterドキュメント(2026)によると、Flexibleは強制的な引き伸ばしなしに柔軟なスペース配分が必要なシナリオ(最小幅のボタン、自然なサイズのテキストブロック、intrinsic constraintsを持つ要素)で必要です。
主要ポイント
Flexibleは、Flexコンテナ内の子要素に柔軟なスペースを提供するラッパーウィジェットです。FlexibleはExpandedと同様に空きスペースの配分に参加しますが、重要な違いがあります:Flexibleの子は、自身のサイズが利用可能なスペースより小さい場合、割り当てられたスペースより少なく占有することができます。
FlexibleはFlutterのFlexアルゴリズムを使用して利用可能なスペースを計算します。まず、フレームワークはすべての非フレキシブルな子(Flexible/Expandedなしのウィジェット)をクエリし、それらの intrinsic size を計算します。残りのスペースは、フレキシブルな子の間でflex係数に比例して分割されます。スペース割り当て後、Flexibleはfitをチェックします — looseの場合、子は「割り当て以上には大きくしない」という制約を受け、小さく留まることができます。
Flexibleの特徴:子ウィジェットに独自の最小サイズがある場合(例:長い文字列のText)、Flexibleは強制的な引き伸ばしなしに要求されたスペースを割り当てます。これにより、Flexibleはコンテナではなくコンテンツによってサイズが決定されるべき要素に不可欠です。
まとめ:要素のスペースを予約したいが、引き伸ばしを強制したくない場合はFlexibleを使用してください。これにより、柔軟なレイアウト配分を維持しながら、コンテンツの自然なサイズが保存されます。
FlexFitはtightとlooseの2つの値を持つ列挙型です。fitの選択により、子ウィジェットが割り当てられたスペースのサイズに強制的に引き伸ばされるかどうかが決まります。
FlexFit.tight:子要素はtight constraintsを受け取ります — 最小サイズと最大サイズが割り当てられたスペースと等しくなります。子はFlexアルゴリズムが割り当てた正確なスペースを占有する必要があります。子が小さい場合は引き伸ばされ、大きい場合は縮小されます。動作はExpandedと同じです。
FlexFit.loose:子要素はloose constraintsを受け取ります — 最小サイズは0、最大サイズは割り当てられたスペースと等しくなります。子は0から最大までの任意のサイズにできます。子が小さい場合(例:短い文字列のText)、自然な幅を占有し、残りのスペースは空のままです。
まとめ:FlexFit.looseはテキストブロックや自然なサイズの要素に適しています。FlexFit.tightはすべての要素が同じ幅または高さを持つ必要がある厳格なカラムレイアウトに適しています。
FlexibleとExpandedは似ていますが、異なるタスクを解決します。Expandedは常に子を引き伸ばして利用可能なすべてのスペースを埋めます。Flexibleは、コンテンツサイズが割り当てられた割合より小さい場合、子の周りに空のスペースを残すことができます。
Flexibleのシナリオ:Row内に2つのボタンがあります。1つ目は「購入」(短いテキスト)、2つ目は「カートに追加」(長いテキスト)。Expandedの場合、両方のボタンが同じ幅に引き伸ばされ、短いテキストに大きなパディングができます。Flexibleの場合、各ボタンはテキストの幅を占有し、空きスペースはボタンの間か端に残ります。
Expandedのシナリオ:Column内に3つのカードがあり、コンテンツに関係なく同じ高さを占有する必要があります。Expandedは利用可能な高さを均等に分割し、各カードは同じサイズに引き伸ばされます。looseのFlexibleはここでは機能しません — 小さなカードは小さなままで、均一なデザインが崩れます。
まとめ:コンテンツが要素のサイズを決定し、周囲の空きスペースが許容される場合はFlexibleを選択してください。コンテンツに関係なくすべての要素が同じサイズである必要がある場合はExpandedを選択してください。
例1は、RowでのFlexFit.looseを使用したFlexibleの基本的な使用法を示しています。
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.amber,
child: const Text('短い'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.cyan,
child: const Text('デモ用の長いテキスト'),
),
),
],
)
この例では、両方のFlexibleがloose fitを使用しています。短いテキストの最初のコンテナは自然な幅を占有し、長いテキストの2つ目は自身の幅を占有します。Rowはそれぞれに利用可能な幅の半分を割り当てますが、loose fitによりコンテナはより小さくなることができ、空きスペースはそれらの間で空のままです。
例2 — ColumnでのTightとLoose fitを使用したFlexibleの比較。
Column(
children: [
Flexible(
fit: FlexFit.tight,
child: const Card(
child: ListTile(
title: Text('Tight — 全高に引き伸ばし'),
),
),
),
const SizedBox(
height: 8,
),
Flexible(
fit: FlexFit.loose,
child: const Card(
child: ListTile(
title: Text('Loose — 自然な高さ'),
),
),
),
],
)
Columnでは、最初のFlexible(tight)がCardを利用可能な高さの半分に引き伸ばします。2番目のFlexible(loose)— Cardはコンテンツに応じて高さを占有し、残りのスペースは空のままです。視覚的に、tightが強制的に領域を埋める一方で、looseがコンパクトなサイズを維持するのがわかります。
まとめ:プロダクションコードでは、Flexible with looseはフォームフィールド、ボタン、テキストブロックに使用されます。Flexible with tightはExpandedと同等で、均等な配分に使用されます。
間違い1:Flexコンテナの外でFlexibleを使用する。Expandedと同様に、FlexibleはRow、Column、Flexの内部にない場合、LayoutExceptionをスローします。解決策:常に親ウィジェットチェーンを確認してください。
間違い2:FlexibleとExpandedを混同する。開発者はloose fitのFlexibleが必要なときにExpandedを、またはその逆をよく使用します。結果:Expandedが短いテキストの要素を引き伸ばし、大きな空のマージンが作成されます。解決策:要素のサイズが割り当てより小さくできる場合は、Flexible(fit: FlexFit.loose)を使用してください。
間違い3:ゼロのflex係数。flex=0のFlexibleは非フレキシブルウィジェットのように動作し、直感的でない場合があります。開発者は柔軟な動作を期待しますが、要素は最小サイズを占有します。解決策:アクティブなスペース配分のためにはflexを≥1にしてください。
間違い4:サイズ制約なしでScrollView内にFlexibleを配置する。SingleChildScrollView内のColumnにFlexibleがある場合、スクロールコンテナは無限のスペースを提供し、flex配分が機能しません。解決策:SizedBoxまたはConstrainedBoxを使用してスクロールコンテナのサイズを制約してください。
まとめ:FlexibleはExpandedと同様に親コンテキストへの注意が必要です。唯一の違いはfitです — タスクに基づいて意図的に選択してください。
よくある質問
Expandedは固定のfit=tightを持つFlexibleです。違いは、Expandedが利用可能なすべてのスペースを埋めるための厳格な拘束を持つ一方、Flexibleは子の自然なサイズを保持するためにloose fitを使用できることです。
異なるテキスト長のボタンには、Flexible(fit: FlexFit.loose)を使用してください。各ボタンはコンテンツの幅を占有し、それらの間に不均衡は生じません。Expandedはすべてのボタンを同じ幅にします。
fit: FlexFit.tightを設定してください — Flexibleは子にすべての割り当てスペースを埋めるよう強制します。このモードでは、Flexibleは動作においてExpandedと完全に同一です。
はい、子が割り当てられたスペースより大きい場合です。FlexibleはFlexコンテナの割合に等しい最大サイズの制約を渡します。子がこのサイズを超える場合、制約内で縮小されます。
はい、FlexibleはRow、Column、および任意の方向を持つ基本Flexウィジェットを含む、あらゆるFlexコンテナと動作します。FlexはmainAxisAlignmentとcrossAxisAlignmentを通じて非標準の方向を設定できます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。