반응형

Jetpack Compose로 UI를 개발하다 보면 위젯의 높이(height) 를 측정해야 하는 상황이 자주 발생합니다.
예를 들어, 특정 위젯의 높이에 따라 다른 컴포넌트의 배치를 조정하거나 애니메이션 효과를 줄 수 있습니다.
이 글에서는 Compose에서 위젯의 높이를 측정하는 방법 4가지를 소개하고, 각 방법의 특징과 사용 팁을 정리합니다.
✅ 1. Layout Composable로 직접 측정하기 (정확도 ★★★★★)
Jetpack Compose의 Layout Composable을 사용하면 자식 컴포넌트의 측정(measure)과 배치(place)를 완전히 제어할 수 있습니다. 정확한 높이 계산이 가능하여 가장 권장되는 방법 중 하나입니다.
@Composable
fun MyWidget(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
Layout(
modifier = modifier,
content = content
) { measurables, constraints ->
val placeables = measurables.map { measurable ->
measurable.measure(constraints)
}
val height = placeables.maxOfOrNull { it.height } ?: 0
val width = placeables.maxOfOrNull { it.width } ?: 0
layout(width, height) {
placeables.forEach { it.placeRelative(0, 0) }
}
}
}
💡 특징
- 자식의 크기를 수동으로 측정하고 레이아웃 구성 가능
- 정밀한 제어가 필요할 때 적합
✅ 2. SubcomposeLayout 사용하기 (측정과 배치 분리 가능, 정확도 ★★★★★)
SubcomposeLayout은 Layout보다 더 유연한 측정 방식으로, 측정 전에 컴포저블을 조건에 따라 분기하거나 동적으로 배치할 수 있습니다.
@Composable
fun MyWidget(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
SubcomposeLayout(modifier = modifier) { constraints ->
val placeables = subcompose(SlotsEnum.Content, content).map {
it.measure(constraints)
}
val height = placeables.maxOfOrNull { it.height } ?: 0
val width = placeables.maxOfOrNull { it.width } ?: 0
layout(width, height) {
placeables.forEach { it.placeRelative(0, 0) }
}
}
}
enum class SlotsEnum { Content }
💡 특징
- 조건부 측정이 가능 (e.g., 특정 상태에서만 측정)
- slot 개념으로 복잡한 UI 처리에 적합
✅ 3. Modifier.onSizeChanged 사용하기 (후처리 방식, 정확도 ★★★★☆)
위젯이 실제로 그려진 이후에 높이를 감지하고 싶을 때는 onSizeChanged를 사용하면 됩니다. UI 렌더링 이후의 후처리용으로 적합합니다.
@Composable
fun MyWidget() {
var height by remember { mutableStateOf(0) }
Box(
modifier = Modifier
.onSizeChanged { size ->
height = size.height
}
) {
// 위젯 내용
}
Text("Widget height: $height")
}
💡 특징
- 위젯이 화면에 렌더링된 이후의 실제 높이 확인 가능
- 애니메이션, 스크롤, 리사이징 등 후처리 용도에 적합
⚠️ 4. LocalView.current.height 사용하기 (제한적, 정확도 ★★☆☆☆)
LocalView를 통해 현재 Android View의 높이를 가져올 수 있지만, Compose의 레이아웃 사이클 외부에서 접근하므로 정확도가 낮고 예측 불가능합니다.
@Composable
fun MyWidget() {
val view = LocalView.current
val height = view.height // 비권장: 정확하지 않을 수 있음
Text("Approximate height: $height")
}
⚠️ 주의사항
- UI가 완전히 그려지기 전에 접근하면 0이 반환될 수 있음
- 되도록 Layout, SubcomposeLayout, onSizeChanged로 대체하는 것이 좋음
🏁 결론: Compose에서 높이를 측정하는 가장 좋은 방법은?
방법 정확도 사용 시점 추천 용도
Layout | ★★★★★ | 측정 시 | 정밀한 배치 필요 시 |
SubcomposeLayout | ★★★★★ | 측정 시 | 조건부 UI 구성 |
onSizeChanged | ★★★★☆ | 렌더링 후 | 동적 높이 감지, 애니메이션 |
LocalView.current.height | ★★☆☆☆ | 외부 접근 | 제한적 상황에서만 사용 |
Jetpack Compose에서는 전통적인 Android View 방식보다 훨씬 더 유연하고 선언적인 방식으로 높이를 측정할 수 있습니다.
상황에 따라 가장 적합한 방법을 선택하여, 더 정확하고 효율적인 UI를 구현해보세요!
반응형