Jetpack Compose navigation 인자와 SavedStateHandle

navigation 인자를 ViewModel에서 SavedStateHandle을 통해 접근할 수 있습니다.

2022/08/30

kotlinandroidjetpack compose

참고: Kickstart Modern Android Development with Jetpack and Kotlin by Catalin Ghita

Jetpack Compose에서 Navigation과 ViewModel을 함께 사용할 때, navigation 인자를 다음과 같이 넣을 수 있습니다.

@Composable
fun RestaurantNavigation() {
    val navController = rememberNavController()
    NavHost(navController = navController, startDestination = "restaurants") {
        
        //...

        composable(
            route = "restaurant/{restaurant_id}",

            // 여기서 인자를 넣습니다. 인자의 이름은 "restaurant_id"입니다.
            arguments = listOf(navArgument("restaurant_id") {
                type = NavType.IntType
            })
            ) {
            RestaurantDetailScreen()
        }
    }
}

이때 navigation 인자는 NavStackEntry에 저장되어, 만약 뷰모델을 쓰지 않는다면 NavStackEntry를 통해 접근할 수 있지만, 뷰모델을 쓴다면 SavedStateHandle을 통해 접근할 수 있습니다. navigation 인자는 SavedStateHandle에 자동으로 저장되기 때문입니다. 따라서 navigation 인자를 Composable이 아닌 ViewModel 내에서 처리할 수 있습니다.

우선 다음과 같이 constructor에 SavedStateHandle을 포함합니다.

class RestaurantDetailsViewModel(
    private val stateHandle: SavedStateHandle
): ViewModel() {

    //...

}

그리고 init {}에서 접근합니다.


//...

init{
    val id = stateHandle.get<Int>("restaurant_id") ?: 0
}

//...

안드로이드 개발자 문서에도 다음과 같은 설명이 있습니다.

이 모듈을 사용하면 ViewModel 객체는 생성자를 통해 SavedStateHandle 객체를 수신합니다. 이 객체는 저장된 상태에 객체를 작성하고 저장된 상태에서 객체를 검색할 수 있게 하는 키-값 맵입니다. 이러한 값은 시스템에서 프로세스가 중단된 후에도 유지되며 동일한 객체를 통해 계속 사용할 수 있습니다.

안드로이드 개발자 문서 바로가기