NavController
에는 '백 스택'이 있습니다. 사용자가 광고를 클릭할 때
님이 방문했습니다. 사용자가 앱 전체에서 화면 간에 이동할 때 NavController
는 대상을 백 스택에 추가하거나 백 스택에서 삭제합니다.
백 스택은 '후입선출' 데이터 구조인 스택입니다. 이
따라서 NavController
는 항목을 상단으로 푸시하고 상단에서 항목을 팝합니다.
있습니다
기본 동작
다음은 백 스택의 동작과 관련하여 고려해야 하는 핵심 사실입니다.
- 첫 번째 대상: 사용자가 앱을 열면
NavController
는 첫 번째 대상을 백 스택의 맨 위로 푸시합니다. - 스택으로 푸시: 각 호출
NavController.navigate()
는 지정된 대상을 스택 상단으로 푸시합니다. - 최상단 대상 팝하기: 위로 또는 뒤로를 탭하면
NavController.navigateUp()
및NavController.popBackStack()
메서드가 각각 호출되어 스택에서 최상단 대상을 팝합니다. 위로와 뒤로의 차이점에 관한 자세한 내용은 탐색 원리 페이지를 참고하세요.
돌아가기
NavController.popBackStack()
메서드는 현재 대상을 백 스택에서 팝하고 이전 대상으로 이동하려고 시도합니다. 이렇게 하면 탐색 기록에서 사용자가 한 단계 뒤로 효과적으로 이동할 수 있습니다. 대상으로 다시 돌아가는지 여부를 나타내는 불리언 값을 반환합니다.
특정 대상으로 돌아가기
popBackStack()
을 사용하여 특정 대상으로 이동할 수도 있습니다. 이렇게 하려면 오버로드 중 하나를 사용하세요. 정수 id
또는 문자열 route
와 같이 식별자를 전달할 수 있는 몇 가지가 있습니다. 이러한 오버로드는 사용자를 지정된 식별자와 연결된 대상으로 이동합니다. 결정적으로, 스택에서 해당 대상 위의 모든 항목을 팝합니다.
이러한 오버로드는 inclusive
불리언도 사용합니다. NavController
가 지정된 대상으로 이동한 후에 이를 백 스택에서 팝해야 하는지도 결정합니다.
예를 들어 다음 간단한 스니펫을 살펴보세요.
navController.popBackStack(R.id.destinationId, true)
여기서 NavController
는 정수 ID가 destinationId
인 대상으로 다시 돌아갑니다. inclusive
인수 값이 true
이므로 NavController
는 지정된 대상을 백 스택에서 팝합니다.
실패한 돌아가기 처리
popBackStack()
이 false
를 반환하면 이후 NavController.getCurrentDestination()
호출에서 null
이 반환됩니다. 즉, 앱이 백 스택에서 마지막 대상을 팝했습니다. 이 경우 사용자는
빈 화면이 표시됩니다.
이는 다음과 같은 경우에 발생할 수 있습니다.
popBackStack()
이 스택에서 아무것도 팝하지 않았습니다.popBackStack()
이 백 스택에서 대상을 팝했으며 이제 스택이 비어 있습니다.
이 문제를 해결하려면 새 대상으로 이동하거나, 활동에서 finish()
를 호출하여 종료해야 합니다. 다음 스니펫은 이 작업을 보여줍니다.
Kotlin
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish()
}
Java
...
if (!navController.popBackStack()) {
// Call finish() on your Activity
finish();
}
대상으로 팝업
한 대상에서 다른 대상으로 이동할 때 백 스택에서 대상을 삭제하려면 연결된 navigate()
함수 호출에 popUpTo()
인수를 추가하세요. popUpTo()
는 navigate()
호출의 일부로 백 스택에서 일부 대상을 삭제하도록 탐색 라이브러리에 지시합니다. 매개변수 값은 백 스택에 있는 대상의 식별자입니다. 식별자는 정수 id
또는 문자열 route
일 수 있습니다.
inclusive
매개변수의 인수를 true
값과 함께 포함하여 popUpTo()
에서 지정한 대상도 백 스택에서 팝해야 함을 나타낼 수 있습니다.
이를 프로그래매틱 방식으로 구현하려면 inclusive
를 true
로 설정하여 NavOptions
의 일부로 popUpTo()
를 navigate()
에 전달합니다. 이는 Compose와 뷰 모두에서 작동합니다.
팝업 시 상태 저장
popUpTo
를 사용하여 대상으로 이동할 때 선택적으로
백 스택 및 모든 대상의 상태가 백 스택에서 팝된 것입니다. 다음과 같은 작업을 할 수 있습니다.
대상으로 이동할 때 백 스택과 대상을 복원합니다.
설정하실 수 있습니다. 이렇게 하면 지정된 대상의 상태를 보존하고
여러 백 스택이 있을 수 있습니다.
프로그래매틱 방식으로 이 작업을 하려면 popUpTo
를 추가할 때 saveState = true
를 지정하세요.
탐색 옵션에 대해 알아보겠습니다.
탐색 옵션에서 restoreState = true
를 지정하여
백 스택 및 관련 상태를 자동으로 복원합니다.
있습니다.
예를 들면 다음과 같습니다.
navController.navigate(
route = route,
navOptions = navOptions {
popUpTo<A>{ saveState = true }
restoreState = true
}
)
XML에서 상태 저장 및 복원을 사용 설정하려면 popUpToSaveState
를 true
로 정의하세요.
연결된 action
에서 각각 true
로서 restoreState
를 사용합니다.
XML 예
다음은 작업을 사용하는 XML의 popUpTo
예입니다.
<action
android:id="@+id/action_a_to_b"
app:destination="@id/b"
app:popUpTo="@+id/a"
app:popUpToInclusive="true"
app:restoreState=”true”
app:popUpToSaveState="true"/>
Compose 예
다음은 Compose에서 이와 동일한 예입니다.
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: Any = A
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = startDestination
) {
composable<A> {
DestinationA(
onNavigateToB = {
// Pop everything up to, and including, the A destination off
// the back stack, saving the back stack and the state of its
// destinations.
// Then restore any previous back stack state associated with
// the B destination.
// Finally navigate to the B destination.
navController.navigate(route = B) {
popUpTo<A> {
inclusive = true
saveState = true
}
restoreState = true
}
},
)
}
composable<B> { DestinationB(/* ... */) }
}
}
@Composable
fun DestinationA(onNavigateToB: () -> Unit) {
Button(onClick = onNavigateToB) {
Text("Go to A")
}
}
보다 세밀하게는 다음과 같이 NavController.navigate()
를 호출하는 방법을 변경할 수 있습니다.
// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a")
}
// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
popUpTo("destination_a") { inclusive = true }
}
// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
launchSingleTop = true
}
NavController.navigate()
에 옵션을 전달하는 방법에 관한 일반적인 정보는 옵션으로 탐색 가이드를 참고하세요.
작업을 사용한 팝
작업을 사용하여 이동할 때 백 스택에서 추가 대상을 팝하도록 선택할 수 있습니다. 예를 들어, 앱에 초기 로그인 흐름이 있다면 사용자가 로그인했을 때 사용자가 뒤로 버튼을 눌러도 로그인 흐름으로 돌아가지 않도록 로그인과 관련된 모든 대상을 백 스택에서 팝해야 합니다.
추가 자료
자세한 내용은 다음 페이지를 참고하세요.
- 순환 탐색: 탐색 흐름이 순환인 경우 과도하게 채워진 백 스택을 방지하는 방법을 알아봅니다.
- 대화상자 대상: 대화상자 대상이 백 스택을 관리하는 방법에 고유한 고려사항을 도입하는 방법을 알아봅니다.