🤖
Jetpack Composeでサイズを取得する
Jetpack Composeでレイアウトを組んでいて要素のサイズを取得することが最近続いたので備忘的に記事化
- Max(Min)XXXの制約を取得する
- Modifier.onGloballyPositionedで取得
- Modifier.layoutで取得
を紹介します。
Max(Min)XXXの制約を取得する
みんな大好きBoxWithConstraints
を使います。
Box
が二つ入ってるColumn
をBoxWithConstraints
で囲んでみます。
BoxWithConstraints(modifier.background(Color.Red)) {
val max = maxHeight
val min = minHeight
Column(
Modifier
.width(80.dp)
) {
Box(modifier = Modifier.height(20.dp).fillMaxWidth().background(color = Color.Blue))
Box(modifier = Modifier.height(20.dp).fillMaxWidth().background(color = Color.Green))
}
}
これでColumn
内のBox
の高さ40dpが取得できると思いがちですが、
あくまでmax/minの制約しか取得できないので、この場合は端末の高さが取得されてしまいます。
※親のComposableは存在しない前提
Modifier.onGloballyPositionedで取得
BoxWithConstraintsと同じようなレイアウトで高さを取得していきます。
val current = LocalDensity.current
Box(modifier.background(Color.Red)) {
var globally = 0.dp
Column(
Modifier
.width(80.dp)
.onGloballyPositioned {
with(current) { globally = it.size.height.toDp() }
}
) {
Box(modifier = Modifier
.height(20.dp)
.fillMaxWidth()
.background(color = Color.Blue))
Box(modifier = Modifier
.height(20.dp)
.fillMaxWidth()
.background(color = Color.Green))
}
}
重要なのはここだけです。
Modifier.onGloballyPositioned {
with(current) { globally = it.size.height.toDp() }
}
この方法なら40dpが取得できます。
Modifier.layoutで取得する
こちらも同じレイアウトを使ってModifier.layoutを使ってみます。
val current = LocalDensity.current
Box(modifier.background(Color.Red)) {
var layout = 0.dp
Column(
Modifier
.width(80.dp)
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
with(current) { layout = placeable.height.toDp() }
layout(placeable.width, placeable.height) {
placeable.placeRelative(0, 0)
}
}
) {
Box(modifier = Modifier
.height(20.dp)
.fillMaxWidth()
.background(color = Color.Blue))
Box(modifier = Modifier
.height(20.dp)
.fillMaxWidth()
.background(color = Color.Green))
}
}
こちらもメインの実装はこんな感じです。
Modifier.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
with(current) { layout = placeable.height.toDp() }
layout(placeable.width, placeable.height) {
placeable.placeRelative(0, 0)
}
}
こちらは本来カスタムレイアウトを作成するための物なので、onGloballyPositioned
を使うよりも無駄な手続きが増えてしまいます。
ただ、こちらも40dpがしっかり取得できるので、場合によっては役に立つかもしれません
Discussion