안드로이드 스터디

JetPack Compose 3편 : Modifier

mky 2025. 12. 30. 21:10
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        //xml은 setContentView
        setContent {
            Column(
                modifier = Modifier
                    .background(Color.Green)
                    .fillMaxHeight(0.5f)
                    .fillMaxWidth()
                    .padding(top = 50.dp)
//                    .requiredWidth(600.dp)
            ) {
                Text("Hello", modifier = Modifier
                    .offset(0.dp, 20.dp)) //world 텍스트를 무시한다.
                Spacer(modifier = Modifier.height(50.dp))
                Text("World")
            }
            //Greeting(name = "Phillip")
        }
    }
}

1. width() vs requireWidth()

  • width()
    • 요청(request) 이다. 즉 희망사항.
    • 부모 레이아웃 제약(constraints)존중
    • 부모가 허용 안 하면 더 작아질 수 있고, 무시될 수도 있음
    • 안전하고 일반적으로 쓰는 방식
  • requireWidth()
    • 강제(require)
    • 부모 제약을 무시하고 강제
    • Modifier.requireWidth(100.dp)에서 부모가 100dp를 허용 못하면? -> IllegalArgumentException 발생 (앱 크래시)
    • 레이아웃 크기가 절대 바뀌면 안 될 때만 사용
  • 자매품 : height / requireHeigh, size / requireSize -> 원리는 똑같다.

2.padding, offset

compose에서는 Modifier에서 여유공간을 만들기 위해 padding, offset을 지원한다. xml에서 자주 쓰였던 margin은 제공되지 않는다.

  • padding : 자신을 기준으로 안쪽으로 얼마나 공간을 비워놓을건지 결정하는 값, 자식 컴포넌트의 크기 측정값에 영향을 준다.
  • offset : 자식 컴포넌트의 크기 측정값에 영향을 주지 않고 자식 컴포넌트를 x축 또는 y축으로 얼만큼 이동할 것인지 결정하는 값

3. Spacer

아무것도 안 그리는데 공간만 차지하는 컴포저블이다. xml의 margin 개념을 대신한다.

위 코드의 실행 결과이다. 패딩과 오프셋이 적용되어 첫 "Hello"텍스트가 눈에 보이기에는 70dp 내려온 것처럼 보인다. 하지만 실제 위치는 맨 상단에서 50dp아래다. 그리고 50dp만큼의 spacer가 적용되고 그 후 "World"텍스트가 나온다.

 

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        //xml은 setContentView
        setContent {
            Column(
                modifier = Modifier
                    .background(Color.Green)
                    .fillMaxHeight(0.5f)
                    .fillMaxWidth()
//                    .padding(top = 50.dp)
                    .border(5.dp, Color.Magenta)
                    .padding(5.dp)
                    .border(5.dp, Color.Blue)
                    .padding(5.dp)
                    .border(5.dp, Color.Red)
                    .padding(10.dp)
            ) {
                Text("Hello", modifier = Modifier
                    .border(5.dp, Color.Yellow)
                    .padding(5.dp)
                    .offset(20.dp, 20.dp)
                    .border(10.dp, Color.Black)
                    .padding(10.dp))
                Spacer(modifier = Modifier.height(50.dp))
                Text("World")
            }
            //Greeting(name = "Phillip")
        }
    }
}

4. border

경계선을 만든다. 귀찮아서 그냥 자세한 설명 생략

 

5.modifier는 순서대로 적용

적용 순서 기준

  1. border(5.dp, Color.Yellow) → 첫 번째 테두리
  2. padding(5.dp) → border 안쪽에 여백 생성
  3. offset(20.dp, 20.dp) → 그려지는 위치만 이동
  4. border(10.dp, Color.Black) → 두 번째 테두리, offset 기준 시각 위치
  5. padding(10.dp) → offset 이후 안쪽 여백

⚠️ Offset만 제외하고는 layout 계산에 모두 반영됨

 

2️⃣ 중복 가능 여부

  • Modifier는 불변 객체 불가, 체이닝 가능
  • 같은 Modifier 여러 번 적용 가능
    • 예: border 두 번
    • 예: padding 여러 번
  • Compose는 마지막 순서가 가장 안쪽 또는 시각적으로 나중에 적용

 

6.clickable{}

클릭 가능하게 한다. {}안에는 클릭 이벤트를 작성한다.