ComposeNavigator.kt
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.navigation.compose
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.core.os.bundleOf
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
/**
* Navigator that navigates through [Composable]s. Every destination using this Navigator must
* set a valid [Composable] by setting it directly on an instantiated [Destination] or calling
* [composable].
*/
@Navigator.Name("composable")
public class ComposeNavigator : Navigator<ComposeNavigator.Destination>() {
private val backstack = mutableListOf<Int>()
override fun navigate(
destination: Destination,
args: Bundle?,
navOptions: NavOptions?,
navigatorExtras: Extras?
): NavDestination? {
if (
navOptions?.shouldLaunchSingleTop() == true && backstack.lastOrNull() == destination.id
) {
return null
}
backstack.add(destination.id)
return destination
}
override fun createDestination(): Destination {
return Destination(this) { }
}
override fun popBackStack(): Boolean {
return backstack.removeLastOrNull() != null
}
override fun onSaveState(): Bundle? {
return bundleOf(KEY_BACK_STACK_IDS to backstack.toIntArray())
}
override fun onRestoreState(savedState: Bundle) {
val restoredBackStack = savedState.getIntArray(KEY_BACK_STACK_IDS)
if (restoredBackStack != null) {
backstack.clear()
backstack.addAll(restoredBackStack.asList())
}
}
/**
* NavDestination specific to [ComposeNavigator]
*/
@NavDestination.ClassType(Composable::class)
public class Destination(
navigator: ComposeNavigator,
internal val content: @Composable (NavBackStackEntry) -> Unit
) : NavDestination(navigator)
private companion object {
private const val KEY_BACK_STACK_IDS = "androidx-nav-compose:navigator:backStackIds"
}
}