diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts index 5abd9d072b180..188e7f64f9726 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle.kts +++ b/packages/SettingsLib/Spa/spa/build.gradle.kts @@ -62,7 +62,7 @@ dependencies { api("androidx.compose.ui:ui-tooling-preview:$jetpackComposeVersion") api("androidx.lifecycle:lifecycle-livedata-ktx") api("androidx.lifecycle:lifecycle-runtime-compose") - api("androidx.navigation:navigation-compose:2.6.0-alpha08") + api("androidx.navigation:navigation-compose:2.7.0-beta01") api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha") api("com.google.android.material:material:1.7.0-alpha03") debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion") diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt index afce16c530c70..08e3a27da1258 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalAnimationApi::class) - package com.android.settingslib.spa.framework import android.content.Intent @@ -24,20 +22,17 @@ import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.annotation.VisibleForTesting -import androidx.compose.animation.AnimatedContentTransitionScope -import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.unit.IntOffset import androidx.core.view.WindowCompat import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController import com.android.settingslib.spa.R import com.android.settingslib.spa.framework.common.LogCategory import com.android.settingslib.spa.framework.common.NullPageProvider @@ -46,12 +41,10 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory import com.android.settingslib.spa.framework.common.createSettingsPage -import com.android.settingslib.spa.framework.compose.AnimatedNavHost import com.android.settingslib.spa.framework.compose.LocalNavController import com.android.settingslib.spa.framework.compose.NavControllerWrapperImpl -import com.android.settingslib.spa.framework.compose.composable +import com.android.settingslib.spa.framework.compose.animatedComposable import com.android.settingslib.spa.framework.compose.localNavController -import com.android.settingslib.spa.framework.compose.rememberAnimatedNavController import com.android.settingslib.spa.framework.theme.SettingsTheme import com.android.settingslib.spa.framework.util.PageLogger import com.android.settingslib.spa.framework.util.getDestination @@ -108,7 +101,7 @@ internal fun BrowseContent( isPageEnabled: (SettingsPage) -> Boolean, initialIntent: Intent?, ) { - val navController = rememberAnimatedNavController() + val navController = rememberNavController() CompositionLocalProvider(navController.localNavController()) { val controller = LocalNavController.current as NavControllerWrapperImpl controller.NavContent(sppRepository.getAllProviders()) { page -> @@ -133,41 +126,15 @@ private fun NavControllerWrapperImpl.NavContent( allProvider: Collection, content: @Composable (SettingsPage) -> Unit, ) { - AnimatedNavHost( + NavHost( navController = navController, startDestination = NullPageProvider.name, ) { - val slideEffect = tween(durationMillis = 300) - val fadeEffect = tween(durationMillis = 300) composable(NullPageProvider.name) {} for (spp in allProvider) { - composable( + animatedComposable( route = spp.name + spp.parameter.navRoute(), arguments = spp.parameter, - enterTransition = { - slideIntoContainer( - AnimatedContentTransitionScope.SlideDirection.Start, - animationSpec = slideEffect - ) + fadeIn(animationSpec = fadeEffect) - }, - exitTransition = { - slideOutOfContainer( - AnimatedContentTransitionScope.SlideDirection.Start, - animationSpec = slideEffect - ) + fadeOut(animationSpec = fadeEffect) - }, - popEnterTransition = { - slideIntoContainer( - AnimatedContentTransitionScope.SlideDirection.End, - animationSpec = slideEffect - ) + fadeIn(animationSpec = fadeEffect) - }, - popExitTransition = { - slideOutOfContainer( - AnimatedContentTransitionScope.SlideDirection.End, - animationSpec = slideEffect - ) + fadeOut(animationSpec = fadeEffect) - }, ) { navBackStackEntry -> val page = remember { spp.createSettingsPage(navBackStackEntry.arguments) } content(page) diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedComposeNavigator.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedComposeNavigator.kt deleted file mode 100644 index 930a83f76e3fc..0000000000000 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedComposeNavigator.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2023 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 com.android.settingslib.spa.framework.compose - -import androidx.compose.animation.AnimatedVisibilityScope -import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -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]. - */ -@ExperimentalAnimationApi -@Navigator.Name("animatedComposable") -public class AnimatedComposeNavigator : Navigator() { - internal val transitionsInProgress get() = state.transitionsInProgress - - internal val backStack get() = state.backStack - - internal val isPop = mutableStateOf(false) - - override fun navigate( - entries: List, - navOptions: NavOptions?, - navigatorExtras: Extras? - ) { - entries.forEach { entry -> - state.pushWithTransition(entry) - } - isPop.value = false - } - - override fun createDestination(): Destination { - return Destination(this, content = { }) - } - - override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) { - state.popWithTransition(popUpTo, savedState) - isPop.value = true - } - - internal fun markTransitionComplete(entry: NavBackStackEntry) { - state.markTransitionComplete(entry) - } - - /** - * NavDestination specific to [AnimatedComposeNavigator] - */ - @ExperimentalAnimationApi - @NavDestination.ClassType(Composable::class) - public class Destination( - navigator: AnimatedComposeNavigator, - internal val content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit - ) : NavDestination(navigator) - - internal companion object { - internal const val NAME = "animatedComposable" - } -} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavGraphBuilder.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavGraphBuilder.kt new file mode 100644 index 0000000000000..192b12500978f --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavGraphBuilder.kt @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2023 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 com.android.settingslib.spa.framework.compose + +import androidx.compose.animation.AnimatedContentScope +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.core.FastOutLinearInEasing +import androidx.compose.animation.core.LinearOutSlowInEasing +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.IntOffset +import androidx.navigation.NamedNavArgument +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavDeepLink +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable + +/** + * Add the [Composable] to the [NavGraphBuilder] with animation + * + * @param route route for the destination + * @param arguments list of arguments to associate with destination + * @param deepLinks list of deep links to associate with the destinations + * @param content composable for the destination + */ +internal fun NavGraphBuilder.animatedComposable( + route: String, + arguments: List = emptyList(), + deepLinks: List = emptyList(), + content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit, +) = composable( + route = route, + arguments = arguments, + deepLinks = deepLinks, + enterTransition = { + slideIntoContainer( + towards = AnimatedContentTransitionScope.SlideDirection.Start, + animationSpec = slideInEffect, + initialOffset = offsetFunc, + ) + fadeIn(animationSpec = fadeInEffect) + }, + exitTransition = { + slideOutOfContainer( + towards = AnimatedContentTransitionScope.SlideDirection.Start, + animationSpec = slideOutEffect, + targetOffset = offsetFunc, + ) + fadeOut(animationSpec = fadeOutEffect) + }, + popEnterTransition = { + slideIntoContainer( + towards = AnimatedContentTransitionScope.SlideDirection.End, + animationSpec = slideInEffect, + initialOffset = offsetFunc, + ) + fadeIn(animationSpec = fadeInEffect) + }, + popExitTransition = { + slideOutOfContainer( + towards = AnimatedContentTransitionScope.SlideDirection.End, + animationSpec = slideOutEffect, + targetOffset = offsetFunc, + ) + fadeOut(animationSpec = fadeOutEffect) + }, + content = content, +) + +private const val FADE_OUT_MILLIS = 75 +private const val FADE_IN_MILLIS = 300 + +private val slideInEffect = tween( + durationMillis = FADE_IN_MILLIS, + delayMillis = FADE_OUT_MILLIS, + easing = LinearOutSlowInEasing, +) +private val slideOutEffect = tween(durationMillis = FADE_IN_MILLIS) +private val fadeOutEffect = tween( + durationMillis = FADE_OUT_MILLIS, + easing = FastOutLinearInEasing, +) +private val fadeInEffect = tween( + durationMillis = FADE_IN_MILLIS, + delayMillis = FADE_OUT_MILLIS, + easing = LinearOutSlowInEasing, +) +private val offsetFunc: (offsetForFullSlide: Int) -> Int = { it.div(5) } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavHost.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavHost.kt deleted file mode 100644 index 81bbc2456577a..0000000000000 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/AnimatedNavHost.kt +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2023 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 com.android.settingslib.spa.framework.compose - -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedContentTransitionScope -import androidx.compose.animation.ContentTransform -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.animation.core.tween -import androidx.compose.animation.core.updateTransition -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.with -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveableStateHolder -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavDestination -import androidx.navigation.NavDestination.Companion.hierarchy -import androidx.navigation.NavGraph -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController -import androidx.navigation.Navigator -import androidx.navigation.compose.DialogHost -import androidx.navigation.compose.DialogNavigator -import androidx.navigation.compose.LocalOwnersProvider -import androidx.navigation.createGraph -import androidx.navigation.get -import kotlinx.coroutines.flow.map - -/** - * Provides in place in the Compose hierarchy for self contained navigation to occur. - * - * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from - * the provided [navController]. - * - * The builder passed into this method is [remember]ed. This means that for this NavHost, the - * contents of the builder cannot be changed. - * - * @param navController the navController for this host - * @param startDestination the route for the start destination - * @param modifier The modifier to be applied to the layout. - * @param route the route for the graph - * @param enterTransition callback to define enter transitions for destination in this host - * @param exitTransition callback to define exit transitions for destination in this host - * @param popEnterTransition callback to define popEnter transitions for destination in this host - * @param popExitTransition callback to define popExit transitions for destination in this host - * @param builder the builder used to construct the graph - */ -@Composable -@ExperimentalAnimationApi -public fun AnimatedNavHost( - navController: NavHostController, - startDestination: String, - modifier: Modifier = Modifier, - contentAlignment: Alignment = Alignment.Center, - route: String? = null, - enterTransition: (AnimatedScope.() -> EnterTransition) = { fadeIn(animationSpec = tween(700)) }, - exitTransition: (AnimatedScope.() -> ExitTransition) = { fadeOut(animationSpec = tween(700)) }, - popEnterTransition: (AnimatedScope.() -> EnterTransition) = enterTransition, - popExitTransition: (AnimatedScope.() -> ExitTransition) = exitTransition, - builder: NavGraphBuilder.() -> Unit -) { - AnimatedNavHost( - navController, - remember(route, startDestination, builder) { - navController.createGraph(startDestination, route, builder) - }, - modifier, - contentAlignment, - enterTransition, - exitTransition, - popEnterTransition, - popExitTransition - ) -} - -/** - * Provides in place in the Compose hierarchy for self contained navigation to occur. - * - * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from - * the provided [navController]. - * - * @param navController the navController for this host - * @param graph the graph for this host - * @param modifier The modifier to be applied to the layout. - * @param enterTransition callback to define enter transitions for destination in this host - * @param exitTransition callback to define exit transitions for destination in this host - * @param popEnterTransition callback to define popEnter transitions for destination in this host - * @param popExitTransition callback to define popExit transitions for destination in this host - */ -@ExperimentalAnimationApi -@Composable -public fun AnimatedNavHost( - navController: NavHostController, - graph: NavGraph, - modifier: Modifier = Modifier, - contentAlignment: Alignment = Alignment.Center, - enterTransition: (AnimatedScope.() -> EnterTransition) = { fadeIn(animationSpec = tween(700)) }, - exitTransition: (AnimatedScope.() -> ExitTransition) = { fadeOut(animationSpec = tween(700)) }, - popEnterTransition: (AnimatedScope.() -> EnterTransition) = enterTransition, - popExitTransition: (AnimatedScope.() -> ExitTransition) = exitTransition, -) { - - val lifecycleOwner = LocalLifecycleOwner.current - val viewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) { - "NavHost requires a ViewModelStoreOwner to be provided via LocalViewModelStoreOwner" - } - val onBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current - val onBackPressedDispatcher = onBackPressedDispatcherOwner?.onBackPressedDispatcher - - // on successful recompose we setup the navController with proper inputs - // after the first time, this will only happen again if one of the inputs changes - navController.setLifecycleOwner(lifecycleOwner) - navController.setViewModelStore(viewModelStoreOwner.viewModelStore) - if (onBackPressedDispatcher != null) { - navController.setOnBackPressedDispatcher(onBackPressedDispatcher) - } - - navController.graph = graph - - val saveableStateHolder = rememberSaveableStateHolder() - - // Find the ComposeNavigator, returning early if it isn't found - // (such as is the case when using TestNavHostController) - val composeNavigator = navController.navigatorProvider.get>( - AnimatedComposeNavigator.NAME - ) as? AnimatedComposeNavigator ?: return - val visibleEntries by remember(navController.visibleEntries) { - navController.visibleEntries.map { - it.filter { entry -> - entry.destination.navigatorName == AnimatedComposeNavigator.NAME - } - } - }.collectAsState(emptyList()) - - val backStackEntry = visibleEntries.lastOrNull() - - if (backStackEntry != null) { - val finalEnter: AnimatedScope.() -> EnterTransition = { - val targetDestination = targetState.destination as AnimatedComposeNavigator.Destination - - if (composeNavigator.isPop.value) { - targetDestination.hierarchy.firstNotNullOfOrNull { destination -> - popEnterTransitions[destination.route]?.invoke(this) - } ?: popEnterTransition.invoke(this) - } else { - targetDestination.hierarchy.firstNotNullOfOrNull { destination -> - enterTransitions[destination.route]?.invoke(this) - } ?: enterTransition.invoke(this) - } - } - - val finalExit: AnimatedScope.() -> ExitTransition = { - val initialDestination = - initialState.destination as AnimatedComposeNavigator.Destination - - if (composeNavigator.isPop.value) { - initialDestination.hierarchy.firstNotNullOfOrNull { destination -> - popExitTransitions[destination.route]?.invoke(this) - } ?: popExitTransition.invoke(this) - } else { - initialDestination.hierarchy.firstNotNullOfOrNull { destination -> - exitTransitions[destination.route]?.invoke(this) - } ?: exitTransition.invoke(this) - } - } - - val transition = updateTransition(backStackEntry, label = "entry") - transition.AnimatedContent( - modifier, - transitionSpec = { - val zIndex = composeNavigator.backStack.value.size.toFloat() - // If the initialState of the AnimatedContent is not in visibleEntries, we are in - // a case where visible has cleared the old state for some reason, so instead of - // attempting to animate away from the initialState, we skip the animation. - if (initialState in visibleEntries) { - ContentTransform(finalEnter(this), finalExit(this), zIndex) - } else { - EnterTransition.None with ExitTransition.None - } - }, - contentAlignment, - contentKey = { it.id } - ) { - // In some specific cases, such as clearing your back stack by changing your - // start destination, AnimatedContent can contain an entry that is no longer - // part of visible entries since it was cleared from the back stack and is not - // animating. In these cases the currentEntry will be null, and in those cases, - // AnimatedContent will just skip attempting to transition the old entry. - // See https://issuetracker.google.com/238686802 - val currentEntry = visibleEntries.lastOrNull { entry -> - it == entry - } - // while in the scope of the composable, we provide the navBackStackEntry as the - // ViewModelStoreOwner and LifecycleOwner - currentEntry?.LocalOwnersProvider(saveableStateHolder) { - (currentEntry.destination as AnimatedComposeNavigator.Destination) - .content(this, currentEntry) - } - } - if (transition.currentState == transition.targetState) { - visibleEntries.forEach { entry -> - composeNavigator.markTransitionComplete(entry) - } - } - } - - val dialogNavigator = navController.navigatorProvider.get>( - "dialog" - ) as? DialogNavigator ?: return - - // Show any dialog destinations - DialogHost(dialogNavigator) -} - -@OptIn(ExperimentalAnimationApi::class) -internal typealias AnimatedScope = AnimatedContentTransitionScope - -@ExperimentalAnimationApi -internal val enterTransitions = mutableMapOf EnterTransition?)?>() - -@ExperimentalAnimationApi -internal val exitTransitions = mutableMapOf ExitTransition?)?>() -@ExperimentalAnimationApi -internal val popEnterTransitions = mutableMapOf EnterTransition?)?>() - -@ExperimentalAnimationApi -internal val popExitTransitions = mutableMapOf ExitTransition?)?>() diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavGraphBuilder.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavGraphBuilder.kt deleted file mode 100644 index bf92f5dda1a98..0000000000000 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavGraphBuilder.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2023 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 com.android.settingslib.spa.framework.compose - -import androidx.compose.animation.AnimatedVisibilityScope -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.runtime.Composable -import androidx.navigation.NamedNavArgument -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavDeepLink -import androidx.navigation.NavGraphBuilder -import androidx.navigation.get - -/** - * Add the [Composable] to the [NavGraphBuilder] - * - * @param route route for the destination - * @param arguments list of arguments to associate with destination - * @param deepLinks list of deep links to associate with the destinations - * @param enterTransition callback to determine the destination's enter transition - * @param exitTransition callback to determine the destination's exit transition - * @param popEnterTransition callback to determine the destination's popEnter transition - * @param popExitTransition callback to determine the destination's popExit transition - * @param content composable for the destination - */ -@ExperimentalAnimationApi -public fun NavGraphBuilder.composable( - route: String, - arguments: List = emptyList(), - deepLinks: List = emptyList(), - enterTransition: (AnimatedScope.() -> EnterTransition?)? = null, - exitTransition: (AnimatedScope.() -> ExitTransition?)? = null, - popEnterTransition: (AnimatedScope.() -> EnterTransition?)? = enterTransition, - popExitTransition: (AnimatedScope.() -> ExitTransition?)? = exitTransition, - content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit -) { - addDestination( - AnimatedComposeNavigator.Destination( - provider[AnimatedComposeNavigator::class], - content - ).apply { - this.route = route - arguments.forEach { (argumentName, argument) -> - addArgument(argumentName, argument) - } - deepLinks.forEach { deepLink -> - addDeepLink(deepLink) - } - enterTransition?.let { enterTransitions[route] = enterTransition } - exitTransition?.let { exitTransitions[route] = exitTransition } - popEnterTransition?.let { popEnterTransitions[route] = popEnterTransition } - popExitTransition?.let { popExitTransitions[route] = popExitTransition } - } - ) -} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavHostController.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavHostController.kt deleted file mode 100644 index a8ac86c2fb15b..0000000000000 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavHostController.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2023 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 com.android.settingslib.spa.framework.compose - -import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.navigation.NavDestination -import androidx.navigation.NavHostController -import androidx.navigation.Navigator -import androidx.navigation.compose.rememberNavController - -/** - * Creates a NavHostController that handles the adding of the [ComposeNavigator], [DialogNavigator] - * and [AnimatedComposeNavigator]. Additional [androidx.navigation.Navigator] instances should be - * added in a [androidx.compose.runtime.SideEffect] block. - * - * @see AnimatedNavHost - */ -@ExperimentalAnimationApi -@Composable -fun rememberAnimatedNavController( - vararg navigators: Navigator -): NavHostController { - val animatedNavigator = remember { AnimatedComposeNavigator() } - return rememberNavController(animatedNavigator, *navigators) -}