본문 바로가기
카테고리 없음

Jetpack Compose에서 위젯 높이 측정하는 4가지 방법 (정확도별 정리)

by h4r3 2025. 4. 17.
반응형

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를 구현해보세요!

 

반응형