๐ŸŒ€Jetpack Compose, @Composable ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•˜์—ฌ

์ด์˜ํ›ˆยท2025๋…„ 4์›” 17์ผ
0

All About Compose

๋ชฉ๋ก ๋ณด๊ธฐ
1/5
post-thumbnail

์•ˆ๋…•ํ•˜์„ธ์š”! ๐Ÿ˜Š

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” @Composable๊ณผ Jetpack Compose์˜ ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์‰ฝ๊ฒŒ, ๊ทธ๋ฆฌ๊ณ  ์ž์„ธํ•˜๊ฒŒ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ธฐ์กด Android View ์‹œ์Šคํ…œ๊ณผ๋Š” ์–ด๋–ค ์ ์ด ๋‹ค๋ฅธ์ง€,
  • @Composable์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€,
  • ๋‚ด๋ถ€์—์„œ ์‹ค์ œ๋กœ ์–ด๋–ค ์ผ์ด ๋ฒŒ์–ด์ง€๋Š”์ง€๊นŒ์ง€

์ฐจ๊ทผ์ฐจ๊ทผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ 1. Jetpack Compose๋Š” ๋ญ๊ฐ€ ๋‹ค๋ฅธ๊ฐ€์š”?

๊ธฐ์กด View ์‹œ์Šคํ…œ

  • TextView, Button๊ณผ ๊ฐ™์€ View ๊ฐ์ฒด๋ฅผ XML๋กœ ์ •์˜ํ•˜๊ณ ,
  • Kotlin/Java ์ฝ”๋“œ์—์„œ findViewById()๋กœ ๊ฐ€์ ธ์™€ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

โžก๏ธ ๋ช…๋ นํ˜• ๋ฐฉ์‹ (Imperative)

"์ด๊ฑธ ๋งŒ๋“ค๊ณ , ์ƒ‰์„ ๋ฐ”๊พธ๊ณ , ์œ„์น˜๋Š” ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•ด!"


Jetpack Compose ๋ฐฉ์‹

  • UI๋ฅผ Kotlin ์ฝ”๋“œ๋กœ ์„ ์–ธํ•˜๊ณ ,
  • ์ƒํƒœ(State)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ UI๊ฐ€ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

โžก๏ธ ์„ ์–ธํ˜• ๋ฐฉ์‹ (Declarative)

"์ด๋Ÿฐ ์ƒํƒœ์ผ ๋•Œ๋Š” ์ด๋ ‡๊ฒŒ UI๋ฅผ ๋ณด์—ฌ์ค˜!"


๐Ÿง  2. @Composable์ด๋ž€?

@Composable์€ โ€œ์ด ํ•จ์ˆ˜๋Š” UI๋ฅผ ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜์•ผโ€ ๋ผ๋Š” ๊ฒƒ์„ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์•Œ๋ ค์ฃผ๋Š” ์ฃผ์„(annotation)์ž…๋‹ˆ๋‹ค.

@Composable
fun Greeting(name: String) {
    Text("Hello, $name")
}

์ด์ฒ˜๋Ÿผ, Compose์—์„œ๋Š” ํ•จ์ˆ˜ ํ•˜๋‚˜๊ฐ€ UI์˜ ๊ตฌ์„ฑ ์š”์†Œ(์ปดํฌ๋„ŒํŠธ)๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
name ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๊ทธ์— ๋”ฐ๋ผ Text()๋„ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.


โš™๏ธ 3. Compose๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ์š”?

์ปดํฌ์ €๋ธ” ํ•จ์ˆ˜ ์‹คํ–‰ ๊ณผ์ •

  1. setContent {} ๋ธ”๋ก์—์„œ ์ปดํฌ์ €๋ธ” ํ•จ์ˆ˜ ์‹คํ–‰์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
  2. Compose๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค UI๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค.
  3. UI๋ฅผ View ๊ณ„์ธต ์—†์ด ์ง์ ‘ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
  4. ์ƒํƒœ(State)๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๊ตฌ์„ฑ(Recomposition)ํ•ฉ๋‹ˆ๋‹ค.
  5. ์ด ๊ณผ์ •์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋„ ํ•จ๊ป˜ ์ด๋ค„์ง‘๋‹ˆ๋‹ค.

๐Ÿ”„ 4. Recomposition์ด๋ž€?

var count by remember { mutableStateOf(0) }

Button(onClick = { count++ }) {
    Text("Count: $count")
}
  • count ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด,
  • Compose๋Š” ํ•ด๋‹น UI๋ฅผ ๋‹ค์‹œ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ณ ,
  • ํ•ด๋‹น ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์„œ ์ƒˆ๋กœ์šด UI๋ฅผ ๊ทธ๋ ค์ค๋‹ˆ๋‹ค.

๐Ÿ‘‰ ์ „์ฒด ํ™”๋ฉด์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ๋˜‘๋˜‘ํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.


๐Ÿงฐ 5. remember, State, ๊ทธ๋ฆฌ๊ณ  Recomposition์˜ ๊ด€๊ณ„

ํ‚ค์›Œ๋“œ์„ค๋ช…
remember์žฌ๊ตฌ์„ฑ๋  ๋•Œ ๊ฐ’์„ ์œ ์ง€ํ•ด์ค๋‹ˆ๋‹ค. (๋กœ์ปฌ ์บ์‹œ์ฒ˜๋Ÿผ ์ž‘๋™)
mutableStateOfCompose์—์„œ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค.
by remember { mutableStateOf() }์ƒํƒœ๊ฐ’์„ ์„ ์–ธํ•˜๋ฉด์„œ, ๋ณ€๊ฒฝ ์‹œ ์žฌ๊ตฌ์„ฑ์„ ์œ ๋„ํ•ฉ๋‹ˆ๋‹ค.
var name by remember { mutableStateOf("world") }

Text("Hello, $name")

์ด ๊ฒฝ์šฐ name ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด Text()๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰๋˜์–ด ์ตœ์‹  UI๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.


๐ŸŽฏ 6. ์ •๋ฆฌํ•˜์ž๋ฉดโ€ฆ

๊ธฐ์กด Android View ์‹œ์Šคํ…œJetpack Compose
XML + findViewByIdKotlin ์ฝ”๋“œ๋กœ UI ์„ ์–ธ
์ƒํƒœ ๋ณ€๊ฒฝ โ†’ ์ˆ˜๋™ UI ์—…๋ฐ์ดํŠธ์ƒํƒœ ๋ณ€๊ฒฝ โ†’ ์ž๋™ Recomposition
ViewGroup๋กœ UI ํŠธ๋ฆฌ ๊ตฌ์„ฑํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ UI ๊ตฌ์„ฑ
๋ช…๋ นํ˜• ๋ฐฉ์‹์„ ์–ธํ˜• ๋ฐฉ์‹

๐Ÿ‘€ ์˜ˆ์ œ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์‚ดํŽด๋ณด๋ฉด?

@Composable
fun Screen() {
    var isLoggedIn by remember { mutableStateOf(false) }

    if (isLoggedIn) {
        Text("Welcome!")
    } else {
        Button(onClick = { isLoggedIn = true }) {
            Text("Login")
        }
    }
}

์œ„ ์ฝ”๋“œ์—์„œ isLoggedIn์ด true๋กœ ๋ฐ”๋€Œ๋ฉด,
Button์ด ์‚ฌ๋ผ์ง€๊ณ  Text("Welcome!")๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ „์ฒด UI๋ฅผ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธด ์˜์—ญ๋งŒ ์Šค๋งˆํŠธํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์ฃ .


์—ฌ๊ธฐ๊นŒ์ง€ Jetpack Compose์˜ ์ž‘๋™ ๋ฐฉ์‹๊ณผ @Composable, ์ƒํƒœ, Recomposition์˜ ๊ด€๊ณ„๋ฅผ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.
๋„์›€์ด ๋˜์…จ๋‹ค๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค! ๋‹ค์Œ ๊ธ€์—์„œ๋Š” LazyColumn์ด๋‚˜ Recomposition, Composition phase์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

profile
์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹น

0๊ฐœ์˜ ๋Œ“๊ธ€