Open3
Expandedとは?
はじめに
Flutterでレイアウトを作成する際、「残りのスペースを全て使いたい」「要素を特定の比率で配置したい」というケースがよくあります。そんな時に便利なのがExpanded
ウィジェットです。
Expandedとは
Expandedは、親のFlexible系ウィジェット(RowやColumn)の中で、利用可能な残りのスペースを埋めるために使用されるウィジェットです。
基本的な使い方
まずは最もシンプルな例を見てみましょう:
Row(
children: [
Container(
width: 100,
color: Colors.blue,
child: Text('固定幅'),
),
Expanded(
child: Container(
color: Colors.red,
child: Text('残りのスペースを埋める'),
),
),
],
)
この例では、青いコンテナが固定幅の100を取り、赤いコンテナが残りの全スペースを占めます。
flexプロパティの活用
複数のExpandedを使用する場合、flex
プロパティで空きスペースの分配比率を指定できます:
Row(
children: [
Expanded(
flex: 2, // 2/3のスペースを取る
child: Container(
color: Colors.blue,
child: Text('2の比率'),
),
),
Expanded(
flex: 1, // 1/3のスペースを取る
child: Container(
color: Colors.red,
child: Text('1の比率'),
),
),
],
)
実践的なユースケース
よくある実装パターンを見てみましょう。例えば、リストビューのアイテムでタイトルと操作ボタンを配置する場合:
ListView.builder(
itemBuilder: (context, index) {
return ListTile(
title: Row(
children: [
Expanded(
child: Text(
'長いタイトルテキストがはみ出さずに表示される',
overflow: TextOverflow.ellipsis,
),
),
IconButton(
icon: Icon(Icons.edit),
onPressed: () {},
),
],
),
);
},
)
注意点
- ExpandedはFlexible系の親ウィジェット内でのみ使用可能
-
flex
の値は1以上の整数である必要がある - 兄弟要素に
Expanded
やFlexible
がない場合、その要素は必要なスペースを優先的に確保する
応用テクニック
nested(入れ子)構造での使用例を見てみましょう:
Column(
children: [
Expanded(
flex: 2,
child: Row(
children: [
Expanded(
child: Container(color: Colors.red),
),
Expanded(
child: Container(color: Colors.blue),
),
],
),
),
Expanded(
flex: 1,
child: Container(color: Colors.green),
),
],
)
この例では、画面を上部2/3と下部1/3に分割し、さらに上部を左右均等に分割しています。
1. Flexibleウィジェットとは
Flexible
ウィジェットは、Row、Column、またはFlexの子ウィジェットの伸縮性を制御するためのウィジェットです。
const Flexible({
Key? key,
int flex = 1,
FlexFit fit = FlexFit.loose,
required Widget child
})
主なプロパティ:
-
flex
: 伸縮係数(デフォルト値: 1) -
fit
: 子ウィジェットの配置方法 -
child
: 子ウィジェット
2. Flexibleの特徴
2.1 伸縮性の制御
Flexibleは、メイン軸方向(Rowの場合は水平方向、Columnの場合は垂直方向)に沿って、利用可能なスペースを柔軟に使用することができます。
Row(
children: [
Flexible(
flex: 2,
child: Container(color: Colors.blue),
),
Flexible(
flex: 1,
child: Container(color: Colors.red),
),
],
)
上記の例では、青いコンテナが利用可能なスペースの2/3、赤いコンテナが1/3を占めます。
2.2 ExpandedとFlexibleの違い
重要な違いとして、Flexibleは以下の特徴があります:
- 子ウィジェットに利用可能なスペースをすべて埋めることを強制しない
-
FlexFit.loose
がデフォルト値として設定されている
// Flexibleの例
Row(
children: [
Flexible(
child: Container(
width: 100, // 指定したサイズが維持される
color: Colors.blue,
),
),
],
)
3. 使用上の注意点
3.1 配置の制約
Flexibleウィジェットは以下の条件を満たす必要があります:
- Row、Column、またはFlexの子孫である必要がある
- Flexibleから親のRow/Column/Flexまでのパスには、StatelessWidgetまたはStatefulWidgetのみが含まれる必要がある
// 正しい使用例
Column(
children: [
Flexible(
child: Container(),
),
],
)
// 誤った使用例(エラーとなる)
Container(
child: Flexible( // Row/Column/Flexの子孫ではないためエラー
child: Text('Error'),
),
)
3.2 FlexFitの設定
fit
プロパティには2つの選択肢があります:
enum FlexFit {
tight, // 利用可能なスペースをすべて埋める
loose, // 子ウィジェットの希望するサイズを尊重
}
4. パフォーマンスと最適化
Flexibleウィジェットは軽量に設計されており、レイアウト計算に大きなオーバーヘッドを追加しません。ただし、以下の点に注意が必要です:
// 推奨される使用方法
Row(
children: [
Flexible(
flex: 1,
child: const SizedBox(), // const を使用して再構築を防ぐ
),
],
)