본문 바로가기

Compose

[Compose] Compose 아키텍처 레이어링

Compose 공식문서를 참고하여 작성하였습니다

 

 

Compose는 여러 모듈로 구성되어 있고 각 모듈은 특정 기능을 담당

 

Compose의 기본 레이어

Compose Layer

 

각 Layer는 하위 수준에 기반하고 상위 수준의 모듈을 만들기 위해 기능 결합

 

Runtime Layer

Compose 런타임의 핵심 기능 (remember, mutableStateOf, @Composable 등)을 제공

Compose가 UI를 어떻게 관리하고 업데이트하는지에 대한 기본적인 기능을 담당

UI 관련 기능은 포함하지 않는다

  • remember: 컴포저블이 다시 실행될 때에도 값을 유지하는 데 사용
  • mutableStateOf: 상태를 변경하고 UI를 업데이트하는 데 사용
  • @Composable: 컴포저블 함수를 선언하는 데 사용
package androidx.compose.runtime

@Composable
fun Example() {
    // remember: 컴포지션이 다시 실행되어도 값 유지
    val myValue = remember { mutableStateOf(0) }

    // 상태를 변경하고 UI 업데이트
    myValue.value++

    // Text Composable 함수 선언
    Text("My value: ${myValue.value}")
}

 

UI Layer

UI 툴킷의 기본 요소 (LayoutNode, Modifier, 입력 핸들러 등)를 구현

UI 요소의 레이아웃, 크기, 위치 등을 제어하는 기능을 제공

  • LayoutNode: UI 트리의 노드를 나타낸다
  • Modifier: UI 요소의 속성을 변경하는 데 사용
  • 입력 핸들러: 사용자의 입력을 처리하는 데 사용
package androidx.compose.ui // Modifier

@Composable
fun Example() {
    Column(
        modifier = Modifier.fillMaxSize(), // Modifier를 통한 UI 요소 속성 변경
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Item 1")
        Spacer(modifier = Modifier.height(8.dp)) // Modifier를 통한 UI 요소 속성 변경
        Text("Item 2")
    }
}

 

Foundation Layer

디자인 시스템에 구속받지 않는 기본적인 UI 구성 요소 (Row, Column, LazyColumn 등)를 제공

UI 레이아웃을 구성하는 데 필요한 기본적인 컴포저블을 제공

자체 디자인 시스템을 구축하는 데 유용

  • Row: UI 요소를 가로 방향으로 배치
  • Column: UI 요소를 세로 방향으로 배치
  • LazyColumn: 많은 수의 UI 요소를 효율적으로 표시
package androidx.compose.foundation.layout // Column

@Composable
fun Example() {
    // Foundation Layer의 Column Composable
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Item 1")
        Spacer(modifier = Modifier.height(8.dp)) // Foundation Layer의 Spacer
        Text("Item 2")
    }
}

 

Material Layer

Material Design 시스템의 구현을 제공

테마, 스타일, 아이콘 등을 포함

Material Design을 사용하는 앱 개발에 필수적이며, 일관성 있는 UI 디자인을 쉽게 구현할 수 있도록 도와줍니다.

@Composable
fun Example() {
    MaterialTheme { // Material Theme 적용
        Button(onClick = {}) {
            Text("Click")
        }
    }
}

 

 

Compose 디자인 원칙

Compose는 작고 집중된 기능들을 조합하여 더 큰 기능을 만드는 방식으로 설계

 

특징

 

제어 (Control)

상위 레벨 구성 요소는 많은 기능을 제공하지만, 개발자가 직접 제어할 수 있는 수준은 낮아진다

더 세밀한 제어가 필요한 경우, 하위 레벨 구성 요소를 직접 사용하도록 dropdown 하면 된다

// 색상을 애니메이션으로 표시하는 API
val color = animateColorAsState(if (condition) Color.Green else Color.Red)

// 항상 회색으로 시작해야 하는 경우, 하위 수준 Animatable API 사용하도록 드롭다운
val color = remember { Animatable(Color.Gray) }
LaunchedEffect(condition) {
    color.animateTo(if (condition) Color.Green else Color.Red)
}

 

 

맞춤 설정 (Customization)

필요에 따라 작은 구성 요소들을 조합하여 상위 레벨 구성 요소를 만들 수 있다


예시) Button Composable 기반으로 만든 GradientButton

@Composable
fun Button(
    // …
    content: @Composable RowScope.() -> Unit
) {
    Surface(/* … */) {
        CompositionLocalProvider(/* … */) { // set LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                Row(
                    // …
                    content = content
                )
            }
        }
    }
}

 

예시) 그라데이션 배경을 지정할 수 있도록 Button을 참조한 Composable

@Composable
fun GradientButton(
    // …
    background: List<Color>,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(onClick = {})
            .background(
                Brush.horizontalGradient(background)
            )
    ) {
        CompositionLocalProvider(/* … */) { // set material LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                content()
            }
        }
    }
}