Compose Modifier 너 뭐냐

벼리·2025년 3월 30일
4

들어가며

해당 문서는 Modifier를 사용해보았다는 전제 하에 진행됩니다. 만약 Modifier에 어떤 메서드가 있는지 궁금하다면 Android Modifier 공식 문서를 참고해주세요💕

Compose 로 개발하다보면 Modifier 를 자주 만나게 됩니다.
몇 번 써보신 분들은 Modifier 가 아래와 같은 기능들을 제공하는 것을 아실 겁니다.

  • 사이즈 수정
  • 클릭 이벤트 구현
  • 배경 수정

그렇다면 Modifier 가 뭐길래 저런 기능들이 있을까요?

지금부터, Modifier 에 대해 알아봅시다!

Modifier란?

Modifier란? 유저가 composable에 장식이나 행동을 부여할 수 있도록 해주는 객체입니다. Modifier 를 통해 추가할 수 있는 기능들은 다음과 같습니다.

  • composable의 크기, layout, 동작 및 모양 변경
  • 접근성을 위한 라벨 정보 더하기
  • 사용자 입력 처리
  • 고수준의 상호작용: 요소를 클릭, 스크롤, 드래그, 확대/축소 가능하게 만들기

Modifier 는 composable의 전체적인 구성, 동작과 연결되어 있습니다. 그렇기에 모든 composable에 modifier 매개변수를 허용하고, 최상위 부모 UI 요소에 modifier를 전달하는 것이 좋습니다. 이렇게 하면 코드의 재사용 가능성이 커지며 코드의 동작이 더 예측 가능해지고 이해하기 쉬워집니다.

Modifier의 사용 유의점

그렇다면, 위의 Modifier를 사용할 때 어떠한 점을 유의해야 할까요

Modifier의 순서

Modifier 메서드의 순서에 따라 적용되는 방식이 달라지기 때문에 적용 순서가 매우 중요합니다.

왜 순서가 달라지면 적용 방식이 달라질까요?

상단의 UI Tree를 보면 composable과 Modifier의 관계를 알 수 있습니다. Modifier는 Layout Node를 위한 Wrapper Node로 표현됩니다.

여기서 Image 컴포넌트의 Modifier를 살펴봅시다. composable에 2개 이상의 Modifier 를 추가하면 modifier 체이닝이 생성됩니다. 여러개의 Modifier를 체이닝하면 각 modifier node는 나머지 chain들과 내부의 layout node을 감쌉니다. Image 컴포넌트에서 clipsize 를 체이닝 했을 때, clip Modifiersize Modifier 를 감싸고 size ModifierImage layout 을 감싸고 있습니다.

이렇게 각 Modifier 메서드는 이전 함수에서 반환한 Modifier를 변경하기 때문에 순서는 최종 결과에 영향을 줍니다.

Modifier 순서에 따라 결과가 달라지는 예시로는 다음과 같습니다.

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .padding(padding)
            .clickable(onClick = onClick)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

padding을 먼저 적용하면, padding Modifier 를 감싼 clickable Modifier 가 생성되기 때문에 padding이 들어간 채 클릭 이벤트가 적용됩니다. 그러나 clickable 을 먼저 적용하면, clickable Modifier 가 생성된 이후에 padding Modifier 가 적용되기 때문에 padding 은 클릭 이벤트가 적용되지 않습니다.

Modifier 매개변수

컴포넌트 전체에 적용되는 Modifier 를 파라미터로 받을 때, 파라미터 이름을 modifier 라고 네이밍을 해야 합니다. 또한 default value로 Modifier 를 할당해야 합니다.

만약 기본 Modifier 가 아닌, 특정 메서드를 적용한 Modifier 를 기본으로 두고 싶다면, modifier 매개변수에 특정 메서드를 추가해야 합니다.

여기서 퀴즈!

ProductListItem(
    product = item,
    onClick = onItemClick,
    modifier = Modifier.width(10.dp)
)
  
@Composable
fun ProductListItem(
    product: Product,
    onClick: (Product) -> Unit,
    modifier: Modifier = Modifier,
) {
    Column(
        modifier = modifier
            .fillMaxSize()
            .clickable {
                onClick(product)
            },
    ) {
    
        // rest of the implementation
    }
}

Column 에는 width(10.dp) 가 적용될까요, fillMaxSize() 가 적용될까요?

정답은 width(10.dp) 입니다!

그렇기 때문에 modifier 에 메서드를 적용하라고 한 겁니다~

만약 전체 컴포넌트가 아닌, 특정 서브 컴포넌트에 modifier를 적용하고 싶다면, 네이밍을 modifier가 아닌 xxModifier 라고 지어야 합니다.

예를 들어서 Button 에만 modifier를 지정하고 싶다면, buttonModifier라고 네이밍을 해야 합니다.

import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun ButtonBar(
    onOk: () -> Unit,
    onCancel: () -> Unit,
    modifier: Modifier = Modifier,
    buttonModifier: Modifier = Modifier
) {
    Row(modifier) {
        Button(onCancel, buttonModifier) { Text("Cancel") }
        Button(onOk, buttonModifier) { Text("Ok") }
    }
}

출처

Modifier  |  API reference  |  Android Developers
Constraints and modifier order  |  Jetpack Compose  |  Android Developers
API Guidelines for Jetpack Compose

profile
코딩일기

0개의 댓글