본문 바로가기

IT/안드로이드 관련

[안드로이드] - Compose 문서 읽어보기 - 2

안녕하세요 남갯입니다 

오늘은 컴포즈 2번째 문서 부분 정리입니다.

 

컴포지션의 생명주기

컴포지션은 초기 컴포지션을 통해서만 생성되고 리컴포지션을 통해서만 업데이트될 수 있습니다. 컴포지션을 수정하는 유일한 방법은 리컴포지션을 통하는 것입니다.

 

 

 

컴포저블이 여러 번 호출되면 컴포지션에 여러 인스턴스가 배치됩니다. 컴퍼지션의 각 호출에는 자체 수명 주기가 있습니다.

 

@Composable
fun MyComposable() {
    Column {
        Text("Hello")
        Text("World")
    }
}

 

컴포지션 내 컴포저블

 

리컴포지션 시 컴포저블이 이전 컴포지션 시 호출한 것과 다른 컴포저블을 호출하는 경우 Compose는 호출되거나 호출되지 않은 컴포저블을 식별하며 두 컴포지션 모두에서 호출된 컴포저블의 경우 입력이 변경되지 않은 경우 재구성하지 않습니다.

 

call site라는 id값을 통해 식별된다.

 

 

@Composable
fun LoginScreen(showError: Boolean) {
    if (showError) {
        LoginError()
    }
    LoginInput() // This call site affects where LoginInput is placed in Composition
}

@Composable
fun LoginInput() { /* ... */ }

 

여기서 LoginInput이 두번불려고 두번째에서는 인풋이 같으므로 호출을 건너뜀

 

 

 

매개변수로 리스트를 넘기게 될경우

 

@Composable
fun MoviesScreen(movies: List<Movie>) {
    Column {
        for (movie in movies) {
            // MovieOverview composables are placed in Composition given its
            // index position in the for loop
            MovieOverview(movie)
        }
    }
}

고유 식별정보가 없으므로  call site라는 식별정보가 아닌

실행순서를 통해 인스턴스를 구분하게 된다.

 

@Composable
fun MovieOverview(movie: Movie) {
    Column {
        // Side effect explained later in the docs. If MovieOverview
        // recomposes, while fetching the image is in progress,
        // it is cancelled and restarted.
        val image = loadNetworkImage(movie.url)
        MovieHeader(image)

        /* ... */
    }
}

위와같이 목록에 새 요소가 추가될때는 기존의 컴포저블은 재사용할 수 없고 모두 다르게 재구성된다.

 

 

리스트의 특정 값을 통해 key를 연결 가능

@Composable
fun MoviesScreen(movies: List<Movie>) {
    Column {
        for (movie in movies) {
            key(movie.id) { // Unique ID for this movie
                MovieOverview(movie)
            }
        }
    }
}

 

 

일부 컴포저블에 key 지원이 내장되어 있음

 

@Composable
fun MoviesScreen(movies: List<Movie>) {
    LazyColumn {
        items(movies, key = { movie -> movie.id }) { movie ->
            MovieOverview(movie)
        }
    }
}

 

 

입력이 변경되지 않을경우 건너뛰기

 

안정적인 유형은 다음 계약을 준수해야 합니다.

  • 두 인스턴스의 equals 결과가 동일한 두 인스턴스의 경우 항상 동일합니다.
  • 유형의 공개 속성이 변경되면 컴포지션에 알림이 전송됩니다.
  • 모든 공개 속성 유형도 안정적입니다.

@Stable 주석을 사용하여 안정적이라고 명시되지 않더라도 Compose 컴파일러가 안정적인 것으로 간주하며 이 계약에 포함되는 중요한 일반 유형이 있습니다.

  • 모든 원시 값 유형: Boolean, Int, Long, Float, Char 
  • 문자열
  • 모든 함수 유형(람다)

 

 

인터페이스의 경우 일반적으로 안정하지 않음으로 간주가 가능해서, Stable을 통해 안정적으로 간주되도록 수정

// Marking the type as stable to favor skipping and smart recompositions.
@Stable
interface UiState<T : Result<T>> {
    val value: T?
    val exception: Throwable?

    val hasError: Boolean
        get() = exception != null
}