ComposeのdefaultMinSizeとsizeInとrequiredSizeInの違い

Kenji Abe
8 min readDec 10, 2023

--

Photo by William Warby on Unsplash

Composeの最小サイズ指定は defaultMinSizesizeInrequiredSizeIn がありますが、これらの違いについてまとめておきます。

これらはどれも最小サイズを指定することができますが、この制約は他の制約がどう影響するかが異なります。

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 は他の sizesizeIn などを指定するとそちらの制約が適用されることになります。

このコードの結果はすべて50dpの正方形になります。

sizeIn

sizeIn は違う制約が指定された場合は条件などにより異なる結果になります。

先程と同じように以下のような 100dpBox で例で見ていきます。

@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 は少しややこしいですが、 sizerequiredSize などの制約はそちらが優先されます。

他の defaultMinSize / sizeIn / requiredSizeIn が指定された場合は Constraints.constrain の挙動に従った結果なります。
今回は最大値を指定してないので、基本的に最小値は大きい値が適用されることになります。

Constraints.constrain の挙動は以下のドキュメントを参照してください。

こちらのほうに2つの制約をどう処理するかが記載されています。

requiredSizeIn

requiredSizeIn は最も強い制約になっていて、基本的に他の制約で変更ができません。

こちらも 100dpBox を使って見ていきます。

@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

基本的に使用することはないかなと思います。コンポーネントがはみ出しても良いから指定のサイズにしたい場合などですかね。

--

--

Kenji Abe
Kenji Abe

Written by Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO

No responses yet