본문 바로가기
Android/Jetpack Compose App

JETPACK COMPOSE: 터치하면 돈이 올라가는 앱을 만들어보자 - 2

by 개발자J의일상 2022. 1. 21.
반응형

지난 시간 리뷰

 

JETPACK COMPOSE: 터치하면 돈이 올라가는 앱을 만들어보자 - 1

 

JETPACK COMPOSE: 터치하면 돈이 올라가는 앱을 만들어보자 - 1

지난 시간 리뷰 Android studio 기본 예제로 알아보는 Jetpack Compose의 기초 Android studio 기본 예제로 알아보는 Jetpack Compose의 기초 What's Jetpack? A library of tools to help developers build moder..

mypark.tistory.com

 

이제 Tap을 클릭했을 때 money가 올라가도록 수정해봅시다!

@Preview
@Composable
fun CreateCircle() {
    var moneyCounter = 0
    Card(modifier = Modifier
        .padding(3.dp)
        .size(100.dp)
        .clickable {
            moneyCounter += 1
            Log.d("Counter", "CreateCircle : $moneyCounter")
        }
        ,
        shape = CircleShape,
        elevation = 4.dp
        ) {
        Box(contentAlignment = Alignment.Center) {
            Text(text = "Tap", modifier = Modifier)
        }

    }
}

CreateCircle()에서 Card에 .clickable을 수정해봅시다!

 

var moneyCounter를 0으로 정의하고 var로 정의하는 이유는 수정 가능해야 하기 때문입니다.

 

var와 val의 차이를 모르시는 분은 아래 링크를 참고하세요~

Kotlin var & val 정리

 

Kotlin var & val 정리

식별자(identifier)에 데이터가 있는 경우 재할당할 수 있는지 여부를 결정해야 합니다. 우리는 프로그램의 요소를 참조하는 식별자를 만들 수 있습니다. 데이터 식별자에 대한 가장 기본적인 결정

mypark.tistory.com

 

우리는 클릭할 때마다 moneyCounter를 1씩 증가시키고 log를 출력하도록 수정하였습니다.

 

 

logcat에서 CreateCircle이 계속 증가하는 것을 알 수 있습니다.

 

이제 Tap 오른쪽에 moneyCounter를 넣어서 증가가 되는지 확인해봅시다!

@Preview
@Composable
fun CreateCircle() {
    var moneyCounter = 0
    Card(modifier = Modifier
        .padding(3.dp)
        .size(100.dp)
        .clickable {
            moneyCounter += 1
            Log.d("Counter", "CreateCircle : $moneyCounter")
        }
        ,
        shape = CircleShape,
        elevation = 4.dp
        ) {
        Box(contentAlignment = Alignment.Center) {
            Text(text = "Tap $moneyCounter", modifier = Modifier)
        }

    }
}

 

Text의 글자안에 $moneyCounter를 넣어 출력하도록 수정하였습니다.

 

헉....? 이게 뭐지 분명 logcat에서는 moneyCounter가 변경이 되는데....

실제 app에서는 그대로 0인 것을 확인할 수 있습니다.

 

왜 이러는 걸까요?

 

compose를 이해하는데 굉장히 중요한 개념이 숨겨져 있습니다.

우리는 composable function을 수정할 때마다 composable을 redraw 해줘야 합니다.

imperative vs declarative approach가 있는데

declarative approach에서는 data를 composable function을 통해 전달하고 composable function은 그 data에 반응합니다.

그럼 여기서 Text에서 data를 받았는데 이걸 어떻게 다시 그릴까요?

Recomposition을 통해 redraw 하면 됩니다.

 

@Preview
@Composable
fun CreateCircle() {
    var moneyCounter by remember {
        mutableStateOf(0)
    }
    Card(modifier = Modifier
        .padding(3.dp)
        .size(100.dp)
        .clickable {
            moneyCounter += 1
            Log.d("Counter", "CreateCircle : $moneyCounter")
        }
        ,
        shape = CircleShape,
        elevation = 4.dp
    ) {
        Box(contentAlignment = Alignment.Center) {
            Text(text = "Tap $moneyCounter", modifier = Modifier)
        }

    }
}

우리는 moneyCounter를 mutableStateOf(0)로 초기화하고 moneyCounter가 바뀔 때마다 Text라는 composable function은 redraw를 하게 됩니다.

mutableStateOf()는 mutable state를 생성하고 이것은 Compose에서 observable type입니다.

값이 변경되면 해당 값을 읽는 composable function의 재구성이 예약됩니다.

 

remeber는 재구성 전반에 걸쳐 상태를 보존하는 데 도움이 됩니다.

 

remember를 사용하지 않고 mutableStateOf만 사용하면 구성 가능 항목이 재구성될 때마다 상태가 0으로 다시 초기화됩니다.

 

앱의 상태는 시간이 지남에 따라 변할 수 있는 값!

Jetpack Compose를 사용하여 Android 앱에서 상태를 저장하고 사용하는 위치와 방법을 명시적으로 나타낼 수 있습니다.

 

핵심 용어: 컴포지션: Jetpack Compose가 컴포저블을 실행할 때 빌드한 UI에 관한 설명

초기 컴포지션: 처음 컴포저블을 실행하여 컴포지션을 만듭니다.

리컴포지션: 데이터가 변경될 때 컴포지션을 업데이트하기 위해 컴포저블을 다시 실행하는 것을 말합니다.

 

https://developer.android.com/jetpack/compose/state?hl=ko

 

300x250

댓글