[Android][compose] 실습

hy3.nji·2023년 8월 6일
1

Jetpack Compose 🎀

목록 보기
5/6

Create an Interactive Dice Roller App

의문점 혹은 인상깊었던 점 혹은 오류


  1. 버튼 컴포넌트와 텍스트 컴포넌트의 작성 방법에 차이가 있을까?

    Button(onClick = {}) {
         Text(stringResource(R.string.roll))
    }
    
    Text(
         text = "sample"
    )
    • Text의 속성은 소괄호() 안에 작성하는 반면, Button의 속성은 대괄호 {} 안에 작성한다. 왜일까? ⇒ 소괄호와 대괄호 안에 작성된 것은 모두 함수에 전달하는 인자(매개변수)이다. Button의 대괄호는 람다 함수이다. 스크린샷 2023-04-02 오후 3.05.22.png ⇒ Button의 매개변수 content로 Text Composable을 전달하였다.
    • Button 내부의 Text에서는 인자를 왜 text = stringResource(R.string.roll) 이 아니라 stringResource(R.string.roll)과 같이 적었을까? ⇒ 다른 인자들은 디폴트 값으로 초기화되어서, 어떤 인자에 매개변수를 할당하였는지 알 수 있기 때문이다.
  2. Image 컴포저블 사용

    @Composable
    fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    		Column(
    		    modifier = modifier,
    		    horizontalAlignment = Alignment.CenterHorizontally
    		){
    				Image(
    		        painter =painterResource(id = R.drawable.dice_1),
    		        contentDescription = "1"
    				)
    		
    				Button(onClick ={}){
    						Text(stringResource(R.string.roll))
    				}
    		}
    }
    • Image 컴포저블에서 painter와 contentDescription은 필수로 매개 변수를 전달해야 하는 인자이다. Image의 함수를 확인해보면 알 수 있다. 다른 인자는 Default 값이 설정되어 있는 반면, painter와 contentDescription은 그렇지 않다. 스크린샷 2023-04-02 오전 1.09.37.png
  3. 오류

    var result by remember { mutableStateOf(1) }
    • Type 'TypeVariable(T)' has no method 'getValue(Nothing?, KProperty<*>)' and thus it cannot serve as a delegate

    ⇒ 솔루션 코드와 비교한 결과 import문 2개가 빠져있었고, 넣었더니 잘 되었다.

    • import androidx.compose.runtime.setValue
    • import androidx.compose.runtime.getValue
    • remember가 뭘까?
      • Remember the value produced by [calculation](https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Function0))[calculation](https://developer.android.com/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Function0)) will only be evaluated during the composition. Recomposition will always return the value produced by composition.

      • 내부 함수

        ```kotlin
        @Composable
        inline fun <T :Any?>remember(crossinline calculation: @DisallowComposableCalls () -> T): T
        ```
        
        - chatgpt 답변 정리
            - 이 코드는 Jetpack Compose 라이브러리에서 사용되는 **`remember`** 함수를 정의하는 코드입니다.
            - **`<T : Any?>`**는 이 함수가 어떤 타입의 값을 기억할 수 있는지를 제한합니다. **`Any?`**는 모든 값이 가능하며, **`T`**는 어떤 타입도 가능하지만 null일 수 있습니다.
            - **`crossinline`** 키워드는 해당 람다식이 비동기로 실행되지 않는다는 것을 보장합니다. 이는 Composable 함수에서는 일부 람다식이 UI 스레드에서 동기적으로 실행되어야 하기 때문입니다.
            - **`@DisallowComposableCalls`** 어노테이션은 이 함수 내에서 다른 Composable 함수가 호출되는 것을 방지합니다. 이는 Composable 함수에서만 사용할 수 있는 함수이므로, 다른 Composable 함수를 호출하는 것은 잘못된 사용입니다.
            - 따라서, **`remember`** 함수는 Composable 함수 내에서 호출되며, 인자로 주어진 람다식을 실행하여 결과를 기억합니다. 이후에 같은 Composable 함수에서 **`remember`** 함수를 다시 호출하면 이전에 계산된 결과를 반환합니다. 이를 통해 UI를 더 효율적으로 구성할 수 있습니다.

        ⇒ 결론 : remember는 인자로 주어진 람다식을 실행하여 결과를 저장하는 역할을 한다.

    • mutableStateOf()는 뭘까?
      • 내부 함수

        ```kotlin
        fun <T> mutableStateOf(
            value: T,
            policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
        ): MutableState<T> = createSnapshotMutableState(value, policy)
        ```
        
        - Return a new `MutableStates` initialized with the passed in Value.
            - `MutableState`
                - A mutable value holder where reads to the value property during the execution of a Composable function.
        - `SnapshotMutationPolicy`?
            - A policy to control how the result of mutableStateOf report and merge changes to the state object.

        ⇒ 결론 : mutableStateOf()전달받은 값으로 새로운 mutableState객체를 초기화해서 리턴한다.

    ⇒ 코드 해석 : result에 mutableState를 1로 초기화한 객체를 저장한다.

    • 그래서 왜 1을 그냥 대입한게 아니라 mutableState 객체를 넣었을까?
      • Composables are stateless by default, which means that they don't hold a value and can be recomposed any time by the system, which results in the value being reset. However, Compose provides a convenient way to avoid this. Composable functions can store an object in memory using the remembercomposable.
      • 컴포저블은 stateless이다. 즉 값을 가지고 있지 않아 시스템에 의해서 언제나 recomposed 될 수 있다. remember를 이용하면 객체를 메모리 상에 저장해둘 수 있다.
      • The mutableStateOf()function returns an observable. You learn more about observables later, but for now this basically means that when the value of the result
        variable changes, a recomposition is triggered, the value of the result is reflected, and the UI refreshes.
      • mutableStateOf()함수는 observable을 반환한다. result 값이 변하면 그 값이 반영되어 UI를 업데이트 한다.
profile
Android Developer

0개의 댓글