Rally에 몇 가지 새로운 기능을 추가해 보자. Row(행)을 클릭하면 개별 계좌의 세부 정보를 표시하는 Account 화면을 추가하자.

Navigation 인자는 경로를 동적으로 만든다. 네비게이션 인자는 하나 이상의 인자를 경로에 전달하고, 인자 타입 또는 기본값을 조정하여 경로 이동 동작을 동적으로 만드는 매우 강력한 도구다.

Note: 명명된 인자는 {argument}와 같이 중괄호로 묶여 경로 내부에 제공된다. 변수 이름을 이스케이핑하기 위해 달러($)기호 를 사용하는 Kotlin의 문자열 템플릿 구문과 유사하다.

RallyActivity에서 Accounts/{name} 인자를 사용하여 기존 NavHost에 새 컴포저블을 추가하고, 그래프에 새 목적지(destination)를 추가한다. 이 목적지에 대해 navArguments 목록도 지정한다. String 타입의 “name”이라는 단일 인자를 정의하자.

val accountsName = RallyScreen.Accounts.name

composable(
    route = "$accountsName/{name}",
    arguments = listOf(
        navArgument("name") {
            // Make argument type safe
            type = NavType.StringType
        }
    )
) {
    // TODO
}

각 컴포저블의 body는 현재 목적지의 경로와 인자를 모델링하는 현 NavBackStackEntry의 매개변수(지금까지 사용하지 않음)를 수신한다. arguments를 사용하여 인자를 가져올 수 있다. 예들 들어, 선택한 계좌의 이름을 UserData에서 찾아 SingleAccountBody 컴포저블로 전달하자.

인자가 제공되지 않은 경우 사용할 기본값을 제공할 수도 있다. 여기서는 필요하지 않기 때문에 생략한다.

코드는 다음과 같다.

val accountsName = RallyScreen.Accounts.name
NavHost(...) {
    ...
    composable(
        "$accountsName/{name}",
        arguments = listOf(
            navArgument("name") {
                // Make argument type safe
                type = NavType.StringType
            }
        )
    ) { entry -> // NavBackStackEntry의 인자들중 "name"을 검색한다.
        val accountName = entry.arguments?.getString("name")
        // UserData에서 일치하는 첫번째 이름을 찾는다. 
        val account = UserData.getAccount(accountName)
        // 계좌를 SingleAccountBody로 전달한다.
        SingleAccountBody(account = account)
    }
}

SingleAccountsBody로 이동하기

이제 컴포저블이 인지로 설정되었으므로, 다음과 같이 navController를 사용하여 컴포저블로 이동할 수 있다.

navController.navigate("${RallyScreen.Accounts.name}/$accountName").

이 함수를 NavHost에서 OverviewBody의 onAccountClick 매개변수와 AccountsBody의 onAccountClick에 추가한다.

재사용 가능한 상태로 유지하려면, 아래와 같이 navigateToSingleAccount 함수와 같은 헬퍼 함수를 만들 수 있다.

fun RallyNavHost(
    ...
) {
    NavHost(
        ...
    ) {
        composable(Overview.name) {
            OverviewBody(
                ...
                onAccountClick = { name ->
                    navigateToSingleAccount(navController, name)
                },
            )
        }
        composable(Accounts.name) {
            AccountsBody(accounts = UserData.accounts) { name ->
                navigateToSingleAccount(
                    navController = navController,
                    accountName = name
                )
            }
        }
        ...
    }
}

private fun navigateToSingleAccount(
    navController: NavHostController,
    accountName: String
) {
    navController.navigate("${Accounts.name}/$accountName")
}

이제 앱을 실행하면, 각 계좌를 클릭할 수 있고 주어진 계좌에 대한 데이터를 표시하는 화면으로 이동한다.

카테고리: Compose

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.