๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Jetpack Compose - Modifier

interfacer_han 2024. 7. 22. 02:22

Jetpack Compose ๊ฒŒ์‹œ๊ธ€ ์‹œ๋ฆฌ์ฆˆ


#1 Modifier

#1-1 ๊ฐœ์š”

 

Modifier  |  Android Developers

androidx.compose.desktop.ui.tooling.preview

developer.android.com

Jetpack Compose๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ์‹์˜ ์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ์—์„œ ์šฐ๋ฆฌ๋Š” XML ์†์„ฑ๊ณผ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ์˜ ๋„ˆ๋น„, ๋†’์ด, ํ‘œ์‹œํ•  ํ…์ŠคํŠธ, ํฌ๊ธฐ, ์Šคํƒ€์ผ ๋ฐ ์ƒ‰์ƒ, ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ ๋ฐ ํŒจ๋”ฉ์„ ์ง€์ •ํ–ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ UI ๊พธ๋ฐˆ ์š”์†Œ๋ฅผ Jetpack Compose์—์„œ๋Š” Modifier๋ผ๋Š” ํด๋ž˜์Šค๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค. Composable ํ•จ์ˆ˜๋“ค์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ modifier: Modifier = Modifier๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์ด Modifier๋ฅผ ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ธ์ˆ˜๋กœ์„œ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ UI๋ฅผ ๊พธ๋ฏผ๋‹ค.

 

๋˜, ๊ธฐ์กด XML์—์„œ ์œ„์ ฏ์˜ ์†์„ฑ์„ ์„ค์ •ํ•˜๋Š” ํ–‰์œ„๊ฐ€ ๊ผญ UI ๊พธ๋ฐˆ์ด๋ผ๋Š” ์‹œ๊ฐ์  ์„ค์ •์— ํ•œ์ •๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์—ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ๋‚˜ ์Šคํฌ๋กค ๊ฐ€๋Šฅ ๋“ฑ์˜ ๋™์ž‘๋„ ํฌ๊ด„ํ–ˆ์—ˆ๋‹ค. Modifier๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ UI ์œ„์ ฏ์˜ ์–ด๋–ค ๋™์ž‘๊นŒ์ง€๋„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

#1-2 ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•œ ๊ตฌํ˜„

val myModifier1 = Modifier
    .background(color = Color.Gray) // ๋ฐฐ๊ฒฝ์ƒ‰์„ ํšŒ์ƒ‰์œผ๋กœ
    .border(10.dp, color = Color.Magenta) //  10dp ๋‘๊ป˜์˜ Magenta ์ƒ‰์„ ๊ฐ€์ง„ border ์„ค์ •
    .padding(10.dp) // 10dp๋งŒํผ padding ์„ค์ •

Modifier๋Š” ์œ„์™€ ๊ฐ™์ด ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•ด ๊ตฌํ˜„๋œ๋‹ค. ์ด ๋ง์€, ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์˜ ์ˆœ์„œ๊ฐ€ ๋งค์šฐ ์ค‘์š”ํ•ด์ง„๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ๋œ๋‹ค.

 

#1-3 ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹ '์ˆœ์„œ'์˜ ์ค‘์š”ํ•จ

val myModifier2 = Modifier
    .wrapContentSize()
    .background(color = Color(0xFFFFC896))
    .border(10.dp, color = Color.White)
    .padding(10.dp)

val myModifier3 = Modifier
    .background(color = Color(0xFFFFC896))
    .border(10.dp, color = Color.White)
    .padding(10.dp)
    .wrapContentSize() // ์•ˆ ๋จนํž˜. ์ด๋ฏธ fillMaxSize()์„ ์‚ฌ์šฉํ•˜๋Š” background(), border(), padding()์ด ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹๋œ ํ›„์ด๊ธฐ ๋•Œ๋ฌธ.

UI์˜ ์ฃผ์š”ํ•œ ๊พธ๋ฐˆ ์š”์†Œ ์ค‘ ํ•˜๋‚˜๋Š” ํ•ด๋‹น UI ์œ„์ ฏ์˜ ํฌ๊ธฐ ์„ค์ •์ผ ๊ฒƒ์ด๋‹ค. Modifier์˜ ํฌ๊ธฐ ๊ธฐ๋ณธ๊ฐ’์€ fillMaxSize()๋กœ ์„ค์ •๋˜์–ด์žˆ๋‹ค. ์ฆ‰, wrapContentSize() ๋“ฑ์œผ๋กœ ํฌ๊ธฐ๋ฅผ ๋ช…์‹œํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์ธ fillMaxSize()๊ฐ€ ์ ์šฉ๋œ๋‹ค. ์ด ๋•Œ, ์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž. myModifier2์™€ myModifier3๋Š” ๊ฐ™์€ Modifier์ผ๊นŒ? ์•„๋‹ˆ๋‹ค. ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

myModifier2๋Š” ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์˜ ์ฒซ๋ฒˆ์งธ ์ˆœ์„œ๋กœ wrapContentSize()์„ ์‚ฌ์šฉํ–ˆ๋‹ค. ์ด ์„ ์ œ์ ์ธ ์‚ฌ์šฉ์— ์˜ํ•ด์„œ ๋’ค์— ์˜ค๋Š” ๋ฉ”์†Œ๋“œ์ธ background(), border(), padding()์ด fillMaxSize() ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ ค์ง€๋Š” ๊ฒƒ์„ ๋ง‰์•˜๋‹ค. ๋ฐ˜๋ฉด, myModifier๋Š” ํฌ๊ธฐ ์กฐ์ ˆ ๋ฉ”์†Œ๋“œ์ธ wrapContentSize()๋ฅผ ๋งจ ๋งˆ์ง€๋ง‰์— ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, ์ด๋ฏธ background(), border(), padding()๊ฐ€ ๊ธฐ๋ณธ ํฌ๊ธฐ์ธ fillMaxSize()๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ด๋ฏธ ๊ทธ๋ ค์ง„ ์ดํ›„๊ธฐ ๋•Œ๋ฌธ์—, wrapContentSize()๋Š” ๋จนํžˆ์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, myModifier3๋Š” ์—ฌ์ „ํžˆ fillMaxSize()๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ, myModifier3์˜ ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์€ ์‹คํŒจํ–ˆ๋‹ค.

 

#2 Modifier๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

// package com.example.modifier

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.modifier.ui.theme.ModifierTheme

val myModifier1 = Modifier
    .background(color = Color.Gray)
    .border(10.dp, color = Color.Magenta)
    .padding(10.dp)

val myModifier2 = Modifier
    .wrapContentSize()
    .background(color = Color(0xFFFFC896))
    .border(10.dp, color = Color.White)
    .padding(10.dp)

val myModifier3 = Modifier
    .background(color = Color(0xFFFFC896))
    .border(10.dp, color = Color.White)
    .padding(10.dp)
    .wrapContentSize() // ์•ˆ ๋จนํž˜. ์ด๋ฏธ fillMaxSize()์„ ์‚ฌ์šฉํ•˜๋Š” background(), border(), padding()์ด ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹๋œ ํ›„์ด๊ธฐ ๋•Œ๋ฌธ.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ModifierTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = Color.Black
                ) {
                    Greeting("Android", myModifier1)
                }

                Surface(
                    modifier = Modifier.fillMaxSize(0.5f),
                    color = Color.Red
                ) {
                    Greeting(name = "Jetpack Compose", myModifier2)
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String, modifierParam: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        fontSize = 32.sp,
        color = Color.Blue,
        fontWeight = FontWeight.Bold,
        textAlign = TextAlign.Center,
        modifier = modifierParam
    )
}

#1-2 ~ #1-3์— ์žˆ๋Š” Modifier๋ฅผ ์ด์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์งฐ๋‹ค. 2๊ฐœ์˜ Surface๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ, Layout์ ์œผ๋กœ ์•„๋ฌด๊ฒƒ๋„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘˜์€ ๊ทธ๋ƒฅ ๊ฒน์ณ์ ธ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

 

#3 ์ž‘๋™ ํ™•์ธ

#3-1 myModifier1๊ณผ myModifier2 ์‚ฌ์šฉ

"Hello Android!"๋ฅผ ํ‘œ์‹œํ•˜๋Š” Greeting()์—๋Š” myModifier1๊ฐ€ ์ ์šฉ๋๋‹ค. myModifier1์—๋Š” ํฌ๊ธฐ์— ๊ด€ํ•ด ์•„๋ฌด๊ฒƒ๋„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜๊ธฐ์— ๊ธฐ๋ณธ๊ฐ’์ธ fillMaxSize()๊ฐ€ ์ ์šฉ๋˜์—ˆ๊ณ  ๋”ฐ๋ผ์„œ Surface๋ฅผ ๊ฐ€๋“ ์ฑ„์› ๋‹ค. ๊ทธ๋ž˜์„œ Surface์˜ color ์†์„ฑ์„ ๊ฒ€์€์ƒ‰์œผ๋กœ ์„ค์ •ํ–ˆ์Œ์—๋„, ํ™”๋ฉด์— ๊ฒ€์€์ƒ‰์ด ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค. myModifier1์˜ ๋ฐฐ๊ฒฝ์ƒ‰์ธ ํšŒ์ƒ‰์ด Surface๋ฅผ ๊ฐ€๋“ ์ฑ„์›Œ๋ฒ„๋ ธ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

"Hello Jetpack Compose!"๋ฅผ ํ‘œ์‹œํ•˜๋Š” Greeting()์—๋Š” myModifier2๊ฐ€ ์ ์šฉ๋๋‹ค. ์ด Greeting()์ด ๋‹ด๊ธด Surface ์ž์ฒด Modifier์— ํฌ๊ธฐ๋ฅผ 1/4๋กœ ๋ช…์‹œํ•ด์„œ ํฌ๊ธฐ๊ฐ€ ์ž‘๋‹ค. myModifier2๋Š” wrapContentSize() ๋ฉ”์†Œ๋“œ๊ฐ€ ์ ์šฉ๋˜์–ด Greeting()์ด Surface๋ฅผ ๊ฐ€๋“ ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ Surface์˜ ๋ฐฐ๊ฒฝ์ƒ‰์ธ ๋นจ๊ฐ„์ƒ‰์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

#3-2 myModifier1๊ณผ myModifier3 ์‚ฌ์šฉ

๋‹ค๋ฅธ ์กฐ๊ฑด์€ ์œ ์ง€ํ•œ ์ฑ„๋กœ myModifier2 ์ž๋ฆฌ์—, ์ด๋ฅธ๋ฐ” ์‹คํŒจํ•œ ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์„ ํ–ˆ๋˜ myModifier3๋ฅผ ๋„ฃ์—ˆ๋‹ค. myModifier3๋ฅผ ๋งŒ๋“ค ๋•Œ ์ˆ˜ํ–‰ํ–ˆ๋˜, ๋ฉ”์†Œ๋“œ ์ฒด์ด๋‹์˜ ๋งˆ์ง€๋ง‰ ์ฒด์ธ์ธ wrapContentSize()๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ๋ชจ์Šต์ด๋‹ค. Greeting()์ด Surface๋ฅผ ๊ฐ€๋“ ์ฑ„์›Œ ๋นจ๊ฐ„์ƒ‰ ๋ฐฐ๊ฒฝ์„ ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค.

 

#4 ์š”์•ฝ

Modifier๋Š” UI Setter๋‹ค.

 

#5 ์™„์„ฑ๋œ ์•ฑ

 

android-practice/jetpack-compose/Modifier at master ยท Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com