Compose 기초 - Compose 아키텍처 레이어링, 설계원칙

Compose 아키텍처 레이어링 (원문)

💡개념이 헷갈리거나 제가 잘 모르거나 많은 사람들이 잘 모를 것 같은 것 위주로 정리

Compose 아키텍쳐의 레이어별 모듈

Jetpack Compose는 다수의 모듈로 만들어졌다. layers 아래 레이어로 내려갈 수록 상위 레이어의 기반이 된다.

Runtime 모듈 : 최하위 레이어

이 모듈은 remember, mutableStateOf, @Composable 주석, SideEffect 같은 Compose 런타임의 기초를 제공한다.

UI가 아닌 Composable 트리 관리 기능만 필요한 경우 이 레이어에 바로 빌드하는 것이 좋다.

UI 모듈

ui-text, ui-graphics, ui-tooling 모듈로 구성된다.

이런 모듈은 LayoutNode, Modifier, 입력 핸들러, 맞춤 레이아웃, 그리기 같은 UI 툴킷의 기본 사항을 구현한다.

UI 툴킷의 기본 개념만 필요한 경우 이 레이어를 기반으로 빌드하는 것이 좋다.

Foundation 모듈

Row, Column, LazyColumn, 특정 동작 인식 같은 디자인 시스템에 구속되지 않는 구성요소를 제공한다.

자체 디자인 시스템을 만들 때는 Foundation 레이어를 기반으로 빌드하는 것이 좋다.

Material 모듈 : 최상위 레이어

머티리얼 디자인 시스템의 구현을 제공하고 테마 설정 시스템, 스타일 적용된 구성요소, 물결 표시, 아이콘도 제공한다.

앱에 머티리얼 디자인을 사용할 때는 이 레이어를 기반으로 빌드한다.

Compose 설계 원칙

많은 제어가 필요할 때 하위수준의 구성요소를 사용한다.

// animateColorAsState()를 사용하면 컬러 변경 트랜지션을 쉽게 적용할 수 있다.
// 하지만 첫 컬러를 다른 컬러로 지정할 수 없다.
// 여기 더해서 애니메이션 실행 시 프레임마다 Recomposition이 발생한다.
val color by animateColorAsState(if (condition) Color.Green else Color.Red)
Log.e("BSSCCO", "RecompositionByAnim")

Box(
    modifier = Modifier
        .fillMaxSize()
        .background(color)
        .clickable { flag = flag.not() }
val color by remember {
    Animatable(Color.Gray)
}
Log.e("BSSCCO", "RecompositionByAnim?")

// 첫 컬러를 다른 컬러로 지정할 수 있다.
// 람다를 사용해 Drawing 단계만 반복되도록 만들었으므로 애니메이션 실행 시 프레임마다 Recomposition이 발생하지 않는다.
LaunchedEffect(condition) {
    color.animateTo(if (condition) Color.Green else Color.Red)
}

Box(
    modifier = Modifier
        .fillMaxSize()
        .drawBehind {
            drawRect(color.value)
        }
        .clickable { flag = flag.not() }

정확한 추상화를 선택한다.

Modifier.pointerInput을 사용하는 것과 달리 Modifier.draggable, Modifier.scrollable, Modifier.swipeable 등을 사용하면 얻는 이점

  • 추상화된 요소이름에서 의도가 드러나서 이해하기 쉽다.
  • 권장사항의 이점을 누릴 수 있다.