#1 개요
Compose 레이아웃 기본사항 | Jetpack Compose | Android Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. Compose 레이아웃 기본사항 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Jetpack Compose를 사용하면 앱의
developer.android.com
위 공식 문서를 나의 언어로 정리했다.
#2 기본 컴포저블
[Android] Jetpack Compose - Layout, Arrangement, Alignment
#1 Layout#1-1 개요 Compose 레이아웃 기본사항 | Jetpack Compose | Android Developers이 페이지는 Cloud Translation API를 통해 번역되었습니다. Compose 레이아웃 기본사항 컬렉션을 사용해 정리하기 내 환경
kenel.tistory.com
Column(), Row(), Box()는 레이아웃을 위해 Jetpack Compose에서 제공되는 기본 컴포저블들이다. 위 게시글에 정리했다.
#3 Layout 설계의 순서
#3-1 코드
@Composable
fun SearchResult() {
Row {
Image(
// ...
)
Column {
Text(
// ...
)
Text(
// ...
)
}
}
}
이 코드의 UI Tree는 아래와 같다.
#3-2 UI Tree
SearchResult
Row
Image
Column
Text
Text
이 UI Tree에 기반해 Layout 내부의 동작 순서를 도식도로 나타내면 아래와 같다.
#3-3 Layout 내부적 동작 순서
회색 네모 속 숫자는 동작 순서다. 자식을 가지는 부모 노드는, 자식들의 크기ㆍ위치를 보고받아 자신의 크기ㆍ위치를 결정한다. 부모가 자신의 크기ㆍ위치를 결정하면, 내부에 자식들을 배치한 뒤에 자신의 부모에게 (재귀적으로) 자기 자신의 크기ㆍ위치를 보고한다. 즉, (시스템 노드를 제외한) 모든 노드는 [측정 요청] → [배치 준비(크기ㆍ위치 결정)] → [실제 배치]의 단계를 거친다.
#3-4 일반화와 예외
Compose의 Layout 단계는 위와 같이 부모 → 자식 방향으로 단 한번만 측정 요청을 하는데, 이는 (2번 이상 측정을 하지 않는다는 점에서) 상대적으로 높은 성능의 비결이 된다. 그러나, 특정 상황에서 여러 번의 측정 요청이 필요할 수도 있는데 이런 경우를 위한 Intrinsic measurements라는 도구가 제공된다. Intrinsic measurements는 자식 컴포저블을 실제로 측정하기 전에, 해당 자식의 최소ㆍ최대 크기를 미리 확인(Query)할 수 있는 기능이다. 이는 '실제 측정'은 아니고 'Query'에 가까운 동작이다. 그렇기에 여전히 단 한번의 측정 요청이라는 규칙은 유지된다.
#4 부모의 제약 조건
Layout을 설계할 때는 다양한 디바이스의 물리적 크기(Form Factor)를 고려해야 한다. Compose에서는 이를 위해 BoxWithConstraints()라는 도구를 제공한다.
@Composable
@UiComposable
fun BoxWithConstraints(
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.TopStart,
propagateMinConstraints: Boolean = false,
content: @Composable @UiComposable BoxWithConstraintsScope.() -> Unit
): Unit
BoxWithConstraints()는 BoxWithConstraintsScope를 보유하는데, 이 Scope에서는 부모 컨테이너의 최소 높이, 최대 높이, 최소 너비, 최대 너비를 참조할 수 있다. 예제 코드는 아래와 같다.
@Composable
fun WithConstraintsComposable() {
BoxWithConstraints {
Text("My minHeight is $minHeight while my maxWidth is $maxWidth")
}
}
/* minHeight 및 maxWidth가 왜 갑자기 튀어나온걸까? 바로, Kotlin의 '암시적 this' 때문.
@Composable
fun WithConstraintsComposable() {
BoxWithConstraints {
// BoxWithConstraintsScope로부터 제공되는 프로퍼티들
val minH = this.minHeight // this는 BoxWithConstraintsScope
val maxW = this.maxWidth
Text("My minHeight is $minH while my maxWidth is $maxW")
}
}
*/
#5 슬롯 기반 Layout
#5-1 개요
슬롯 기반 레이아웃(Slot-based layout)은 컴포저블에 사용자화(customization)의 여지가 존재하는 레이아웃을 의미한다. 사용자화가 가능한 부분부분들을 '슬롯(Slot)'이라 부르는데 Drawer, FloatingActionButton, TopAppBar와 같은 요소들이 그 예다. 개발자는 이 슬롯들을 원하는 방식으로 채울 수 있다.
#5-2 슬롯 커스텀의 예시
@Composable
fun HomeScreen(/*...*/) {
ModalNavigationDrawer(drawerContent = { /* ... */ }) {
Scaffold(
topBar = { /*...*/ }
) { contentPadding ->
// ...
}
}
}
Scaffold()가 쓰인 코드다. 컴포저블을 위치시킬 수 있는 람다 함수 @Composable () -> Unit는 대부분 "content"라는 이름의 프로퍼티로 존재한다. 이 프로퍼티가 Slot의 자리다.
'깨알 개념 > Android' 카테고리의 다른 글
[Android] UI architecture - Phase와 State (1) | 2025.02.27 |
---|---|
[Android] UI architecture - Phases (0) | 2025.02.27 |
[Android] Pointer input - Nested Scroll (0) | 2025.02.18 |
[Android] Pointer input - Scroll (0) | 2025.02.17 |
[Android] Pointer input - Gesture (0) | 2025.02.08 |