#1 ๊ฐ์
์ํ ๋ฐ Jetpack Compose | Android Developers
์ด ํ์ด์ง๋ Cloud Translation API๋ฅผ ํตํด ๋ฒ์ญ๋์์ต๋๋ค. ์ํ ๋ฐ Jetpack Compose ์ปฌ๋ ์ ์ ์ฌ์ฉํด ์ ๋ฆฌํ๊ธฐ ๋ด ํ๊ฒฝ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฝํ ์ธ ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฅํ์ธ์. ์ฑ์ ์ํ๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ
developer.android.com
Jetpack Compose์ State ๊ฐ๋
์ ๋ํด ์ดํด๋ณธ๋ค.
#2 ์ผ๋ฐ์ ์ธ ๊ฐ๋ ์ผ๋ก์์ State
๋จผ์ , State๋ผ๋ ์ฉ์ด ์์ฒด์ ๋ํ ์ดํด๊ฐ ํ์ํ๋ค. Jetpack Compose์์ ์ฐ์ด๋ State๊ฐ ์๋๋ผ ์ผ๋ฐ์ ์ธ ๊ฐ๋
์ผ๋ก์์ State ๋ง์ด๋ค. ์ํ๋ผ๋ ๋ง๋ก ๋ฒ์ญ๋๋ State๋ ๋ง ๊ทธ๋๋ก ์ํ, ์ฆ ์๊ฐ์ด ํ๋ฆ์ ๋ฐ๋ผ ๋ณํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฐ์ผ๋ก ๋ค๋ฆ์๋ ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ๋งํ๋ ๊ฒ์ด๋ค.
// ์ผ๋ฐ์ ์ธ State๋ฅผ ๋ํ๋ด๋ ํด๋์ค
class Counter {
private var count = 0
// ์ํ๋ฅผ ์ฝ๋ ํจ์
fun getCount(): Int {
return count
}
// ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์
fun increment() {
count++
}
fun decrement() {
count--
}
}
ํ๋กํผํฐ count๋ฅผ State๋ก ๋ณผ ์ ๋ ์๊ณ , Counter ํด๋์ค๋ฅผ State๋ก ๋ณผ ์๋ ์๋ค. State๋ผ๋ ์ฉ์ด ์์ฒด๋ ๊ต์ฅํ ์ถ์์ ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
#3 Jetpack Compose์์์ State
#3-1 ์กฐ๊ฑด - UI์ ํ์๋๋ ๋ณ์
๊ทธ๋ ๋ค๋ฉด ์ด Jetpack Compose์์ ์ฐ์ด๋ State๋ ๋ฌด์์ธ๊ฐ? ๋ฑ ๋ด๋ ์ผ๋ฐ์ ์ธ ๊ฐ๋
์ผ๋ก์์ State๋ณด๋ค๋ ๋ ๊ตฌ์ฒด์ ์ธ ์๋ฏธ๋ก ์ฐ์ผ ๊ฒ์ด๋ค. UI์ ๊ด๋ จ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Jetpack Compose ๋ต๊ฒ, Jetpack Compose์์์ State๋ UI์ ํ์๋๋ ์์น, ๋ ์ ํํ๋ UI์ ํ์๋๋ ๋ณ์๋ค. #2์์ State๋ ์๊ฐ์ด ํ๋ฆ์ ๋ณํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฐ์ด๋ผ๊ณ ํ๋ค. ๋ฐ๋ผ์ ๊ฐ์ด ํ๋ ์ฝ๋ฉ๋์ด ์์ ๋ฆฌ๋ ์์ผ๋ '์์น' ๋ณด๋ค๋ '๋ณ์'๋ผ๊ณ ํด์ผ ๋ ์ ํํ ํํ์ด๋ค.
ํ์ง๋ง, Jetpack Compose์ State๋ UI์ ํ์๋๋ ๋ณ์๋ผ๋ ๋ง์ ๋ถ์ถฉ๋ถํ ์ค๋ช
์ด๋ค. ์๋ ์ฝ๋๋ฅผ ๋ณด์.
var count = 0 // count๋ Intํ
@Composable
fun ButtonExample(modifierParam: Modifier = Modifier) {
Button(
onClick = {
Log.i("interfacer_han", "Current count value: ${++count}")
},
modifier = modifierParam
) {
Text(
text = "Count: $count",
fontSize = 40.sp
)
}
}
count๊ฐ Text()์์ ์ฐธ์กฐ๋๊ณ ์๋ค. ์ฆ, count๋ UI์ ํ์๋๋ ๋ณ์๋ค. ์ด ๋ count๋ 'State'์ธ๊ฐ? ์๋๋ค. ์ผ๋ฐ์ ์ธ ๊ฐ๋
์ผ๋ก์์ State๋ ๋ง์ง๋ง, Jetpack Compose์์ ๋งํ๋ State๊ฐ ๋๋ ค๋ฉด ํ ๊ฐ์ง ์กฐ๊ฑด์ด ๋ ํ์ํ๋ค.
#3-2 ์กฐ๊ฑด - Observable ํจํด ๊ตฌํ
๋ฐ๋ก Jetpack Compose์ State๋ ๋ฐ๋์ Observable ํจํด์ ๊ตฌํํด์ผ๋ง ํ๋ค๋ ์กฐ๊ฑด ๋๋ฌธ์ด๋ค. #2์ count๋ ํ๋ฒํ Intํ ๋ณ์๋ก Observable ํจํด๊ณผ๋ ๊ด๊ณ๊ฐ ์๋ค. ๋ฐ๋ผ์ State๋ผ๊ณ ํ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด count๋ฅผ Intํ์ด ์๋๋ผ Observable ํจํด์ ๊ตฌํํ ๋ฐ์ดํฐํ์ผ๋ก ๋ฐ๊พธ๋ฉด ๊ทธ๋ง์ผ ๊ฒ์ด๋ค. ๊ทธ ๋ฐ์ดํฐํ์ผ๋ก๋ MutableState, LiveData, Flow ๋๋ RxJava๊ฐ ์๋ค. count๋ฅผ ์ด๋ฌํ ๋ฐ์ดํฐํ์ผ๋ก ๋ฐ๊ฟ๋ณด๋ฉด,
val count = mutableStateOf(0) // count๋ MutableState<Int>ํ
@Composable
fun ButtonExample(modifierParam: Modifier = Modifier) {
Button(
onClick = {
Log.i("interfacer_han", "Current count value: ${++count.value}")
},
modifier = modifierParam
) {
Text(
text = "Count: ${count.value}",
fontSize = 40.sp
)
}
}
๋น๋ก์ count๋ (Jetpack Compose์) State๊ฐ ๋๋ค.
#4 State์ ํน๊ถ
#4-1 ํ๋ค๊ฒ(?) State๋ฅผ ๋ง๋ค์ด ๋๋ ์ด์
์ด๋ป๊ฒ ๋ณด๋ฉด ๋นก๋นกํ๋ค๊ณ ๋ ๋ณผ ์ ์๋ 2๊ฐ์ง ์กฐ๊ฑด์ ๋ง์กฑํด์ผ๋ง ์ป์ด์ง๋ Jetpack Compose์ State์๊ฒ๋ ํน๊ถ์ด ์ฃผ์ด์ง๋๋ฐ, ๋ฐ๋ก ํด๋น State ๊ฐ์ ๋ณํ๊ฐ Jetpack Compose ๋ฐํ์์ ์ํด ์๋์ผ๋ก ์ถ์ ๋๊ณ UI ์ ๋ฐ์ดํธ๊น์ง ์์์ ์ผ๋ก ์งํ๋๋ค๋ ์ ์ด๋ค (LiveData.observe()์ ์์์ ์ํ์ ๋ค๋ฃฌ ์ด ๊ฒ์๊ธ๊ณผ ๊ฐ์ ๋งฅ๋ฝ์ ๋์์ ํ๋ค). ์ฆ, State๋ฅผ ๋ง๋ค์ด๋ง ๋๋ฉด ํ๋ก๊ทธ๋๋จธ๋ ๊ทธ ๋ค์ ์ผ์ ์ ๊ฒฝ ๋ ์ ์๋ค.
State์ ํน๊ถ์ ์ฒด๊ฐํ๊ธฐ ์ํด์, ์ค์ ์ฑ์ ์คํ์์ผ ๊ทธ ๋์์ ์ดํด๋ณด๊ฒ ๋ค. ์์์ ๋ค๋ค๋ count ๋ณ์๊ฐ, State์ธ ๊ฒฝ์ฐ์ State๊ฐ ์๋ ๊ฒฝ์ฐ ๊ฐ๊ฐ์ ์๋๋ก์ด๋ ์๋ฎฌ๋ ์ดํฐ๋ก ์คํ์ํจ๋ค.
#4-2 ๋ณ์ count๊ฐ State๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋์

count๊ฐ State๊ฐ ์๋์๋ #3-1๋ฅผ ์ค์ ๋ก ์คํ์ํจ ๋ค์ ๋ฒํผ์ ํด๋ฆญํ์ ๋ ์ผ์ด๋๋ ์ผ์ด๋ค. Log ๋ฉ์์ง๋ฅผ ๋ณด๋ฉด count๋ ๋ฒํผ์ ๋๋ฅผ ๋๋ง๋ค ๋ถ๋ช
ํ ์ฆ๊ฐํ๊ณ ์์ง๋ง, UI์์ ์
๋ฐ์ดํธ๊ฐ ์ด๋ค์ง์ง ์์ count๊ฐ ๊ณ์ 0์ธ ๊ฑธ๋ก ๋ณด์ธ๋ค. ๋ฌผ๋ก ์ ์ด์ Button์ ํด๋ฆญ๋ฆฌ์ค๋์์ Text ์
๋ฐ์ดํธ์ ๊ดํ ์ฝ๋๋ฅผ ์จ ๋ฃ์ง ์์๊ธฐ ๋๋ฌธ์ด์ง๋ง ๋ง์ด๋ค (์ฌ๋ด์ด์ง๋ง ์ฌ์ค, Jetpack Compose๋ ์ ์ธ์ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ์ Button() ํด๋ฆญ ์ ๊ทธ ๋ด๋ถ์ Text()๋ฅผ ์
๋ฐ์ดํธํ๋ ์ฝ๋๋ฅผ ์ง๋ ๊ฒ ์์ฒด๊ฐ ์ค๊ณ์ ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น๋ค ๋ฐ๋ผ์, ์ด์ฐ๋ณด๋ฉด Jetpack Compose์์์ State ์ฌ์ฉ์ ํน๊ถ์ด๋ผ๊ธฐ๋ณด๋จ ์๋ฌด๋ผ๊ณ ๋ด์ํ ์ง๋ ๋ชจ๋ฅธ๋ค).
#4-3 ๋ณ์ count๊ฐ State์ธ ๊ฒฝ์ฐ์ ๋์

๋ฐ๋ฉด, count๊ฐ State์๋ #3-2์ ์ฝ๋๋ฅผ ์คํ์ํค๋ฉด UI ์
๋ฐ์ดํธ๊ฐ ์ด๋ค์ง๋ค. count๊ฐ State์ด๊ธฐ ๋๋ฌธ์ด๋ค. Compose ๋ฐํ์์ ์๋ก์ด State์ ๋ฐ์ดํฐ๋ก Composable์ ๋ค์ ์คํํด ์
๋ฐ์ดํธ๋ UI๋ฅผ ํ๋ฉด์ ์ถ๋ ฅํ๋ค. ์ด๋ฅผ ์ฌ๊ตฌ์ฑ(Recomposition)์ด๋ผ๊ณ ํ๋ค.
#5 LiveData์์ ๋น๊ต ์ฐ์
#5-1 ๊ฐ๊ฒฐํจ (์ ์ธ์ )
LiveData๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ช ์์ ์ผ๋ก ๊ตฌํํด์ผ ํ๋ ์ฝ๋๊ฐ ์๋์ ์ผ๋ก ๋ ๋ง๋ค. ์๋ฅผ ๋ค์ด, LiveData๋ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์์ ๋ ์ด๋ฅผ ๊ด์ฐฐ(observe)ํ๊ณ , ๊ทธ์ ๋ฐ๋ผ UI๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด XML ๋ ์ด์์์ด๋ ViewModel์ ๋ณ๋์ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ค. ์ด ๊ณผ์ ์์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ณ ๋ คํ Observable ํจํด์ ์ค์ ํ๊ณ ๊ด๋ฆฌํด์ผ ํ๋ฉฐ, ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๋ฐ๋ฅธ UI ์ ๋ฐ์ดํธ๋ฅผ ๋ช ์์ ์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ค. ์ด๋ก ์ธํด ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ณ ๋ณต์กํด์ง ์ ์๋ค. ๋ฌผ๋ก LiveData๋ LiveData ์ถ๋ฒ ์ ์ ์ฝ๋๋ค์ ๋นํ๋ฉด ์ถฉ๋ถํ ์ ์ธ์ ์ด์ง๋ง, Jetpack Compose ํ๊ฒฝ์์์ State ๋ฌธ๋ฒ๋งํผ ์ ์ธ์ ์ด์ง๋ ์๋ค.
#5-2 Jetpack Compose์์ ํตํฉ์ฑ
State๋ Jetpack Compose์์ ํตํฉ์ ๊ณ ๋ คํ์ฌ ์ค๊ณ๋์๋ค. Compose์ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๋๋์ด ์ถ๊ฐ์ ์ธ Observer ์ค์ ์ด๋ ์๋ช ์ฃผ๊ธฐ ๊ด๋ฆฌ ์์ด State.value์ ๋ณํ์ ๋ฐ๋ผ UI๊ฐ ์๋์ผ๋ก ์ฌ๊ตฌ์ฑ(Recomposition)๋๋ค.
#6 ์์ฝ
UI์ ํ์๋๋ ๋ณ์๋ฉด์, ๋์์ Observable ํจํด๊น์ง ์ถฉ์กฑํด์ผ๋ง ๋น๋ก์ Jetpack Compose์ State๋ค. State.value๊ฐ ๋ณํ๋ฉด Recomposition์ด ์์์ ์ผ๋ก ์ํ๋๋ค.
#7 ์์ฑ๋ ์ฑ
android-practice/jetpack-compose/StateBasics at master ยท Kanmanemone/android-practice
Contribute to Kanmanemone/android-practice development by creating an account on GitHub.
github.com
#3-1 ~ #3-2์ ์ฝ๋๊ฐ ๋ด๊ธด ์๋๋ก์ด๋ ํ๋ก์ ํธ๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] Jetpack Compose - State Hoisting (0) | 2024.07.23 |
---|---|
[Android] Jetpack Compose - State Remembering (0) | 2024.07.23 |
[Android] Jetpack Compose - Lazy Column (0) | 2024.07.22 |
[Android] Jetpack Compose - Button (0) | 2024.07.22 |
[Android] Jetpack Compose - Layout, Arrangement, Alignment (0) | 2024.07.22 |