| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 동성로핫플
- 앱개발
- 개발자
- 대구핫플
- 인스타핫플
- 애드센스
- 범물동카페
- 감성카페
- 대구맛집
- 수성구카페
- 지산동카페
- 코딩공부
- 안드로이드스튜디오
- 안드로이드개발
- 안드로이드
- 안드로이드앱개발
- 동성로맛집
- androidstudio
- Android
- 선언형ui
- 대구카페
- 안드로이드앱
- 코딩
- 동성로카페
- 수성구맛집
- 대구인스타핫플
- 의무경찰
- compose
- 파이썬
- 어플개발
Archives
- Today
- Total
Glacier's Daily Log
[Android] Compose의 SubcomposeLayout이란? 본문
반응형
SubcomposeLayout이란?
SubcomposeLayout은 Jetpack Compose의 레이아웃 API.
컴포저블을 순차적으로 측정하고, 측정 결과를 바탕으로 다른 컴포저블의 크기를 결정할 수 있다.
일반적인 Compose의 문제점(?)
일반적으로 Compose는 모든 컴포저블을 동시에 측정함. 예를 들어:
- 배경 Box와 텍스트가 동시에 측정됨
- 텍스트 높이를 모르는 상태에서 배경 높이를 결정해야 함
- onSizeChanged는 측정 후에 호출되어 리컴포지션이 필요함
SubcomposeLayout을 통한 해결법
SubcomposeLayout은 측정 순서를 제어할 수 있음:
- 먼저 텍스트를 측정해 높이를 얻음
- 그 높이로 배경 높이를 계산
- 계산된 높이로 배경을 측정
- 최종적으로 배치
현업에서 SubcomposeLayout으로 문제를 해결한 경험
문제 상황
- 박스 위에 겹쳐있는 텍스트 위젯의 높이에따라, 박스 배경 높이가 달라져야 하는 상황.
- 하지만 Column으로 묶여있거나 하는 상황이 아니기 때문에 두개 높이를 동기화하기 쉽지 않음
실패한 시도1
기존 코드는 onSizeChanged로 텍스트 높이를 측정해봄
Text(...)
.onSizeChanged { size ->
subtitleTextHeightDp = size.height.toDp()
}
- onSizeChanged는 측정 후 비동기로 호출됨
- 프리뷰에서는 첫 렌더링 시 높이가 0으로 시작
- 배경이 먼저 그려지고 텍스트 높이는 나중에 업데이트됨
- 따라서 원하는 결과 (텍스트 높이에 맞춰 뒷 배경 높이가 동적으로 바뀌어야함) 가 나오지 않음
해결 방법: SubcomposeLayout 적용
1단계: 텍스트 먼저 측정
val textPlaceable = subcompose("text") {
Text(
text = panelCard.subTitle,
style = XXXDesignSystemTypo.title01,
)
}[0].measure(constraints)
subtitleTextHeightDp = textPlaceable.height.toDp()
- subcompose("text"): 텍스트 컴포저블 생성
- .measure(constraints): 실제 크기 측정
- 측정된 높이를 변수에 저장
2단계: 배경 높이 계산
val backgroundHeight = if (panelCard.subTitle.isNotEmpty()) {
XXXDesignSystemSpacing.spacing24 +
subtitleTextHeightDp +
XXXDesignSystemSpacing.spacing20 +
} else { 0.dp } + 104.dp - 15.dp
- 측정된 텍스트 높이로 배경 높이 계산
3단계: 배경 레이아웃 측정
val backgroundPlaceable = subcompose("background") {
Box(
modifier = Modifier.height(backgroundHeight) // 계산된 높이 사용
.background(backgroundColor)
)
}[0].measure(constraints.copy(maxHeight = backgroundHeightPx))
- 계산된 높이로 배경 측정
4단계: 최종 배치
layout(constraints.maxWidth, contentPlaceable.height) {
backgroundPlaceable.placeRelative(0, 0) // 배경을 먼저 배치
textPlaceable.placeRelative(0, 0) // 컨텐츠를 위에 배치
}
- 배경과 컨텐츠를 같은 위치에 겹쳐 배치

요약
- 측정 순서 제어: 텍스트 → 배경 → 컨텐츠 순서로 측정
- 동기적 측정: onSizeChanged 대신 measure()로 즉시 높이 획득
- 프리뷰 호환성: 프리뷰에서도 첫 렌더링부터 정확한 높이 계산
반응형
Comments