Composeの最小サイズ指定は defaultMinSize
と sizeIn
と requiredSizeIn
がありますが、これらの違いについてまとめておきます。
これらはどれも最小サイズを指定することができますが、この制約は他の制約がどう影響するかが異なります。
defaultMinSize
defaultMinSize
は一番制約としては弱いものになり、他の制約がないときだけ適用されるものになります。
以下のような defaultMinSize
を適用した Box
コンポーネントについて見ていきます。 100dp
の正方形を描画しています。
@Composable
fun DefaultMinBox(modifier: Modifier = Modifier) {
Box(
modifier = modifier
.defaultMinSize(
minWidth = 100.dp,
minHeight = 100.dp
)
.background(Color.Red)
)
}
このコンポーネントに別の制約を追加するようにして違いを見てきます。
// 以下はすべて 50.dp の Box になる
DefaultMinBox(
modifier = Modifier.size(50.dp)
)
DefaultMinBox(
modifier = Modifier.requiredSize(50.dp)
)
DefaultMinBox(
modifier = Modifier.defaultMinSize(minWidth = 50.dp, minHeight = 50.dp)
)
DefaultMinBox(
modifier = Modifier.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
DefaultMinBox(
modifier = Modifier.requiredSizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
defaultMinSize
は他の size
や sizeIn
などを指定するとそちらの制約が適用されることになります。
このコードの結果はすべて50dpの正方形になります。
sizeIn
sizeIn
は違う制約が指定された場合は条件などにより異なる結果になります。
先程と同じように以下のような 100dp
の Box
で例で見ていきます。
@Composable
fun SizeMinBox(modifier: Modifier = Modifier) {
Box(
modifier = modifier
.sizeIn(
minWidth = 100.dp,
minHeight = 100.dp
)
.background(Color.Blue)
)
}
こちらも別の制約を追加するようにして違いを見てきます。
// 直接サイズ指定した場合はそちらの値になる => 50.dp
SizeMinBox(
modifier = Modifier.size(50.dp)
)
SizeMinBox(
modifier = Modifier.requiredSize(50.dp)
)
// 元々指定されてる値より小さい最小値を指定した場合はいずれも変更されない => 100.dp のまま
// (Constraintsの挙動に準拠)
SizeMinBox(
modifier = Modifier.defaultMinSize(minWidth = 50.dp, minHeight = 50.dp)
)
SizeMinBox(
modifier = Modifier.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
SizeMinBox(
modifier = Modifier.requiredSizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
// 元々指定されてる値より大きい最小値を指定した場合は大きい方に変更される => 200.dp のまま
// (Constraintsの挙動に準拠)
SizeMinBox(
modifier = Modifier.defaultMinSize(minWidth = 200.dp, minHeight = 200.dp)
)
SizeMinBox(
modifier = Modifier.sizeIn(minWidth = 200.dp, minHeight = 200.dp)
)
RequiredSizeMinBox(
modifier = Modifier.requiredSizeIn(minWidth = 200.dp, minHeight = 200.dp)
)
sizeIn
は少しややこしいですが、 size
や requiredSize
などの制約はそちらが優先されます。
他の defaultMinSize
/ sizeIn
/ requiredSizeIn
が指定された場合は Constraints.constrain
の挙動に従った結果なります。
今回は最大値を指定してないので、基本的に最小値は大きい値が適用されることになります。
Constraints.constrain
の挙動は以下のドキュメントを参照してください。
こちらのほうに2つの制約をどう処理するかが記載されています。
requiredSizeIn
requiredSizeIn は最も強い制約になっていて、基本的に他の制約で変更ができません。
こちらも 100dp
の Box
を使って見ていきます。
@Composable
fun RequiredSizeMinBox(modifier: Modifier = Modifier) {
Box(
modifier = modifier
.requiredSizeIn(
minWidth = 100.dp,
minHeight = 100.dp
)
.background(Color.Magenta)
)
}
別の制約を追加するようにして違いを見てきます。
// 100.dpのBoxが中央からはみ出して表示される
RequiredSizeMinBox(
modifier = Modifier.size(50.dp)
)
RequiredSizeMinBox(
modifier = Modifier.requiredSize(50.dp)
)
// 100.dpのまま変更されない
RequiredSizeMinBox(
modifier = Modifier.defaultMinSize(minWidth = 50.dp, minHeight = 50.dp)
)
RequiredSizeMinBox(
modifier = Modifier.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
RequiredSizeMinBox(
modifier = Modifier.requiredSizeIn(minWidth = 50.dp, minHeight = 50.dp)
)
// 200.dpのスペースの中に中央に100.dpのBoxが表示される
RequiredSizeMinBox(
modifier = Modifier.defaultMinSize(minWidth = 200.dp, minHeight = 200.dp)
)
RequiredSizeMinBox(
modifier = Modifier.sizeIn(minWidth = 200.dp, minHeight = 200.dp)
)
RequiredSizeMinBox(
modifier = Modifier.requiredSizeIn(minWidth = 200.dp, minHeight = 200.dp)
)
requiredSizeIn
の場合は基本的にその値が優先されます。
他の制約のほうが小さい場合は強制的に中央寄せではみ出して表示され、大きい場合は中央に指定サイズで表示されることになります。
結構ややこしいのが sizeIn
と組み合わせたときに、どちらが先に Modifier
に設定されてるかで挙動が変わるので、前述の sizeIn
のほうも参照してください。
使い分け
最後に個人的な考えになりますが、使い分けとしては以下のような感じになるかなと思います。
defaultMinSize
共通コンポーネントなどの再利用するもので、場合によっては制約を変更したい場合に適していると思います。
sizeIn
画面個別のコンポーネントなどで再利用することがなく、基本的に制約が変更されないものに使用すると良いと思います。
requiredSizeIn
基本的に使用することはないかなと思います。コンポーネントがはみ出しても良いから指定のサイズにしたい場合などですかね。