【Flutter Widget】「FittedBox」を学ぼう
こんにちは、Saeです。
私は「さえないエンジニア」から「さえたエンジニア」へクラスチェンジするために、日々レベル上げに勤しんでます。
今日は「FittedBox」というWidgetについて解説していきます。
また今回使用しているサンプルコードはGithubで公開しております。参考になれば幸いです。
この記事で書いてあること
- 忙しい人のための「FittedBox」
- FittedBoxとは
- FittedBoxはどういう動きをするのか
- 「Fit」でスケーリングの手法を変える方法
忙しい人のための「FittedBox」
日々忙しさで忙殺されているエンジニアへ向けた「FittedBox」の説明です。
ここだけ見れば、なんとなくわかります。
「FittedBoxで囲ったら、親Widgetに合わせてスケーリング」
「Fitプロパティでスケーリング方法が変わる」
FittedBoxとは
それではここから詳しく「FittedBox」について説明していきます。
そもそもFittedBoxとは何なのでしょうか。
公式ドキュメントには以下のように記載されてます。
fit に従って子をスケールし、ウィジェット内に配置するウィジェットを作成します。
https://api.flutter.dev/flutter/widgets/FittedBox-class.html
要はFittedBoxで囲った子要素を、
親要素に合わせてスケーリング(自動的に拡大・縮小)させるWidgetということですね。
FittedBoxはどういう動きをするのか
では実際のコードと実行結果を見ながら、FittedBoxはどういう動きをするのか見ていきましょう。
Fitted box 非適用
// 親Widget(Container)
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: containerWidth,
height: containerHeight,
// 子Widget(Text)
child: const Text(
'Fitted Box is not applied',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
Fitted box 適用
// 親Widget(Container)
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: containerWidth,
height: containerHeight,
// FittedBox
// 親WidgetのContainerに合わせて、FittedBoxの子Widget(Text)がスケーリングする
child: const FittedBox(
// 子Widget(Text)
child: Text(
'Apply Fitted Box',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
実行結果
実行結果から、親WidgetのContainerに合わせて、
FittedBoxの子Widget(Text)がスケーリングしていることがわかったかと思います。
「Fit」を使って、スケーリングの手法を変えよう
FittedBoxでは、FItというプロパティを変えることでスケーリングの手法を変えることができます。
Fitの種類は以下になります。
プロパティ名 | 実際の動き |
---|---|
fill | アスペクト比を変えて、親要素の幅・高さに合わせる |
contain | 親要素内におさめ、また子要素のアスペクト比を崩さずに可能な限り大きくする |
cover | 親要素全体を埋めつつ、子要素のサイズをできるだけ小さくする |
fitWidth | 親要素から垂直方向にはみ出しても、子要素の幅はおさまるように表示する |
fitHeight | 親要素から水平方向にはみ出しても、子要素の高さはおさまるように表示する |
none | 子要素を親要素に配置(デフォルトはセンタリング)し、親要素の外部分はすべて破棄して表示する |
scaleDown | 子要素を親要素に配置(デフォルトはセンタリング)し、必要に応じて小さくおさまるように表示 |
文面だけだとイメージがつきにくいと思うので、
最後に実際のコードと実行結果を確認しながら、挙動を確認していきましょう。
Fill
- アスペクト比を変えて、親要素の幅・高さに合わせる
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: containerWidth,
height: containerHeight,
child: const FittedBox(
// fill: アスペクト比を変えて、親要素の幅・高さに合わせる
fit: BoxFit.fill,
child: Text(
'Apply Fitted Box',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
contain
- 親要素内におさめ、また子要素のアスペクト比を崩さずに可能な限り大きくする
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: containerWidth,
height: containerHeight,
child: const FittedBox(
// contain: 親要素内におさめ、また子要素のアスペクト比を崩さずに可能な限り大きくする
fit: BoxFit.contain,
child: Text(
'Apply Fitted Box',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
cover
- 親要素全体を埋めつつ、子要素のサイズをできるだけ小さくする
- はみ出した部分を切り取る場合は、clipBehaviorプロパティを使用する
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 100,
height: 25,
child: const FittedBox(
// cover: 親要素全体を埋めつつ、子要素のサイズをできるだけ小さくする
fit: BoxFit.cover,
// はみ出した部分を切り取る場合は、clipBehaviorプロパティを使用する
clipBehavior: Clip.hardEdge,
child: Text(
'Apply Fitted Box',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
fitWidth
- 親要素から垂直方向にはみ出しても、子要素の幅はおさまるように表示する
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 150,
height: 50,
child: const FittedBox(
// fitWidth: 親要素から垂直方向にはみ出しても、子要素の幅はおさまるように表示する
fit: BoxFit.fitWidth,
child: Text(
'Apply Fitted\r\nBox',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
fitHeight
- 親要素から水平方向にはみ出しても、子要素の高さはおさまるように表示する
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 100,
height: 75,
child: const FittedBox(
// fitHeight: 親要素から水平方向にはみ出しても、子要素の高さはおさまるように表示する
fit: BoxFit.fitHeight,
child: Text(
'Apply Fitted\r\nBox',
style: TextStyle(
backgroundColor: Colors.greenAccent,
),
),
),
),
none
- 子要素を親要素に配置(デフォルトはセンタリング)し、親要素の外部分はすべて破棄して表示する
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 50,
height: 50,
child: FittedBox(
// none: 子要素を親要素に配置(デフォルトはセンタリング)し、親要素の外部分はすべて破棄して表示する
fit: BoxFit.none,
child: Text(
'Apply Fitted\r\nBox',
style: TextStyle(
fontSize: 25,
backgroundColor: Colors.greenAccent.withOpacity(0.5),
),
),
),
),
scaleDown
- 子要素を親要素に配置(デフォルトはセンタリング)し、必要に応じて小さくおさまるように表示
// Container 小サイズ
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 100,
height: 50,
child: const FittedBox(
// scaleDown: 子要素を親要素に配置(デフォルトはセンタリング)し、必要に応じて小さくおさまるように表示
fit: BoxFit.scaleDown,
child: Text(
'Apply Fitted Box',
style: TextStyle(
fontSize: 100,
backgroundColor: Colors.greenAccent,
),
),
),
),
// Container 大サイズ
Container(
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.blueAccent,
),
),
width: 200,
height: 50,
child: const FittedBox(
// scaleDown: 子要素を親要素に配置(デフォルトはセンタリング)し、必要に応じて小さくおさまるように表示
fit: BoxFit.scaleDown,
child: Text(
'Apply Fitted Box',
style: TextStyle(
fontSize: 100,
backgroundColor: Colors.greenAccent,
),
),
),
),
Discussion
ちょうど調べたいなぁ〜って思ってたところなので非常に有難いですmm