Flexible: その概要、動作原理、モバイル開発での設定方法

著者: IT Sectr 公開日: 2026-07-03 読了時間: 6 分

Flexibleは、Flexコンテナ内で子要素が利用可能なスペースをどのように占有するかを制御するFlutterウィジェットです。Expandedとは異なり、Flexibleは子に割り当てられた領域全体を埋めることを強制しません — 子ウィジェットは小さくてもよく、残りのスペースは空のままです。公式のFlutterドキュメント(2026)によると、Flexibleは強制的な引き伸ばしなしに柔軟なスペース配分が必要なシナリオ(最小幅のボタン、自然なサイズのテキストブロック、intrinsic constraintsを持つ要素)で必要です。

主要ポイント

  • FlexibleはRow、Column、Flexでの柔軟なスペース配分のためのレイアウトウィジェットです
  • FlexFit.looseは子が割り当てられたスペースより小さくなることを許可し、FlexFit.tightは埋めることを強制します
  • Flexibleをlooseで使用すると、サイズがコンテンツによって決定されるべきウィジェットに適しています
  • Expandedとの違い: Expandedにはfitパラメータがなく、常にtightとして動作します
  • Flex係数はFlexibleとExpandedの両方で同じように機能します — 空きスペースの割合

Flexibleとは

Flexibleは、Flexコンテナ内の子要素に柔軟なスペースを提供するラッパーウィジェットです。FlexibleはExpandedと同様に空きスペースの配分に参加しますが、重要な違いがあります:Flexibleの子は、自身のサイズが利用可能なスペースより小さい場合、割り当てられたスペースより少なく占有することができます。

FlexibleはFlutterのFlexアルゴリズムを使用して利用可能なスペースを計算します。まず、フレームワークはすべての非フレキシブルな子(Flexible/Expandedなしのウィジェット)をクエリし、それらの intrinsic size を計算します。残りのスペースは、フレキシブルな子の間でflex係数に比例して分割されます。スペース割り当て後、Flexibleはfitをチェックします — looseの場合、子は「割り当て以上には大きくしない」という制約を受け、小さく留まることができます。

Flexibleの特徴:子ウィジェットに独自の最小サイズがある場合(例:長い文字列のText)、Flexibleは強制的な引き伸ばしなしに要求されたスペースを割り当てます。これにより、Flexibleはコンテナではなくコンテンツによってサイズが決定されるべき要素に不可欠です。

まとめ:要素のスペースを予約したいが、引き伸ばしを強制したくない場合はFlexibleを使用してください。これにより、柔軟なレイアウト配分を維持しながら、コンテンツの自然なサイズが保存されます。

FlexFit.tight vs FlexFit.loose

FlexFitはtightとlooseの2つの値を持つ列挙型です。fitの選択により、子ウィジェットが割り当てられたスペースのサイズに強制的に引き伸ばされるかどうかが決まります。

FlexFit.tight:子要素はtight constraintsを受け取ります — 最小サイズと最大サイズが割り当てられたスペースと等しくなります。子はFlexアルゴリズムが割り当てた正確なスペースを占有する必要があります。子が小さい場合は引き伸ばされ、大きい場合は縮小されます。動作はExpandedと同じです。

FlexFit.loose:子要素はloose constraintsを受け取ります — 最小サイズは0、最大サイズは割り当てられたスペースと等しくなります。子は0から最大までの任意のサイズにできます。子が小さい場合(例:短い文字列のText)、自然な幅を占有し、残りのスペースは空のままです。

まとめ:FlexFit.looseはテキストブロックや自然なサイズの要素に適しています。FlexFit.tightはすべての要素が同じ幅または高さを持つ必要がある厳格なカラムレイアウトに適しています。

Expandedの代わりにFlexibleを使用するタイミング

FlexibleExpandedは似ていますが、異なるタスクを解決します。Expandedは常に子を引き伸ばして利用可能なすべてのスペースを埋めます。Flexibleは、コンテンツサイズが割り当てられた割合より小さい場合、子の周りに空のスペースを残すことができます。

Flexibleのシナリオ:Row内に2つのボタンがあります。1つ目は「購入」(短いテキスト)、2つ目は「カートに追加」(長いテキスト)。Expandedの場合、両方のボタンが同じ幅に引き伸ばされ、短いテキストに大きなパディングができます。Flexibleの場合、各ボタンはテキストの幅を占有し、空きスペースはボタンの間か端に残ります。

Expandedのシナリオ:Column内に3つのカードがあり、コンテンツに関係なく同じ高さを占有する必要があります。Expandedは利用可能な高さを均等に分割し、各カードは同じサイズに引き伸ばされます。looseのFlexibleはここでは機能しません — 小さなカードは小さなままで、均一なデザインが崩れます。

まとめ:コンテンツが要素のサイズを決定し、周囲の空きスペースが許容される場合はFlexibleを選択してください。コンテンツに関係なくすべての要素が同じサイズである必要がある場合はExpandedを選択してください。

Flexibleを使用したコード例

例1は、RowでのFlexFit.looseを使用したFlexibleの基本的な使用法を示しています。

dart
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の比較。

dart
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と同等で、均等な配分に使用されます。

Flexible使用時の一般的な間違い

間違い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です — タスクに基づいて意図的に選択してください。

よくある質問

FlexibleとExpandedの違いは何ですか?

Expandedは固定のfit=tightを持つFlexibleです。違いは、Expandedが利用可能なすべてのスペースを埋めるための厳格な拘束を持つ一方、Flexibleは子の自然なサイズを保持するためにloose fitを使用できることです。

Rowのボタンにはどのfitを選ぶべきですか?

異なるテキスト長のボタンには、Flexible(fit: FlexFit.loose)を使用してください。各ボタンはコンテンツの幅を占有し、それらの間に不均衡は生じません。Expandedはすべてのボタンを同じ幅にします。

FlexibleをExpandedのように動作させるには?

fit: FlexFit.tightを設定してください — Flexibleは子にすべての割り当てスペースを埋めるよう強制します。このモードでは、Flexibleは動作においてExpandedと完全に同一です。

Flexibleは子のサイズを縮小できますか?

はい、子が割り当てられたスペースより大きい場合です。FlexibleはFlexコンテナの割合に等しい最大サイズの制約を渡します。子がこのサイズを超える場合、制約内で縮小されます。

FlexibleはFlexコンテナと直接動作しますか?

はい、FlexibleはRow、Column、および任意の方向を持つ基本Flexウィジェットを含む、あらゆるFlexコンテナと動作します。FlexはmainAxisAlignmentとcrossAxisAlignmentを通じて非標準の方向を設定できます。

まとめ

  • Flexibleは子を強制的に引き伸ばさずに柔軟なスペース配分を行うウィジェットです
  • FlexFit.looseはコンテンツの自然なサイズを保持し、FlexFit.tightは強制的に領域を埋めます
  • Expandedはfit=tightのFlexibleの特殊ケースです。fitを選択する必要がある場合はFlexibleを使用してください
  • Flex係数はFlexibleとExpandedの両方で同じように機能します — 空きスペースの割合
  • Loose fitはボタン、テキストブロック、動的コンテンツを持つ要素に最適です
  • 推奨:サイズがコンテンツによって決定されるコンポーネントにはFlexible with looseを使用してください

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください