From 1f48a509b66bc7cfe9a0bc44347c3d1fa25d0fd1 Mon Sep 17 00:00:00 2001 From: Aleksander Nowakowski Date: Thu, 5 Dec 2024 15:42:09 +0100 Subject: [PATCH] Custom navigation transitions --- .../navigation/NavigationDestination.kt | 83 +++++++++++++++++-- .../common/navigation/NavigationView.kt | 17 ++-- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationDestination.kt b/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationDestination.kt index 5226d04d..b05c34d6 100644 --- a/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationDestination.kt +++ b/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationDestination.kt @@ -33,11 +33,18 @@ package no.nordicsemi.android.common.navigation +import androidx.compose.animation.AnimatedContentScope +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.animation.SizeTransform import androidx.compose.runtime.Composable import androidx.compose.ui.window.DialogProperties +import androidx.navigation.NavBackStackEntry /** * A navigation view allows navigating between different destinations. + * * @property id The destination id. */ sealed class NavigationDestination( @@ -58,16 +65,42 @@ sealed class NavigationDestination( * This class binds a destination identifier with a composable function that will be used to * render the content. * - * @property id The destination identifier. - * @property content The composable function that will be used to render the content. + * @param id The destination identifier. + * @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 sizeTransform Callback to determine the destination's sizeTransform. + * @param content The composable function that will be used to render the content. */ internal class ComposableDestination( id: DestinationId<*, *>, - val content: @Composable () -> Unit, + val enterTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> EnterTransition?)?, + val exitTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> ExitTransition?)?, + val popEnterTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> EnterTransition?)?, + val popExitTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> ExitTransition?)?, + val sizeTransform: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> SizeTransform?)?, + val content: @Composable AnimatedContentScope.() -> Unit, ): NavigationDestination(id) /** * Definition of an inner navigation. + * + * This class binds a destination identifier with a composable function that will be used to + * render the content. + * + * @property id The destination identifier. + * @property destinations The list of inner destinations. */ internal class InnerNavigationDestination( id: DestinationId<*, *>, @@ -80,8 +113,9 @@ internal class InnerNavigationDestination( * This class binds a destination identifier with a composable function that will be used to * render the content. * - * @property id The destination identifier. - * @property content The composable function that will be used to render the content. + * @param id The destination identifier. + * @param dialogProperties The dialog properties. + * @param content The composable function that will be used to render the content. */ internal class DialogDestination( id: DestinationId<*, *>, @@ -91,14 +125,45 @@ internal class DialogDestination( /** * Helper method for creating a composable [NavigationDestination]. + * + * @param id The destination identifier. + * @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 sizeTransform Callback to determine the destination's sizeTransform. + * @param content The composable function that will be used to render the content. */ fun defineDestination( id: DestinationId<*, *>, - content: @Composable () -> Unit -): NavigationDestination = ComposableDestination(id, content) + enterTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> EnterTransition?)? = + null, + exitTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> ExitTransition?)? = + null, + popEnterTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> EnterTransition?)? = + enterTransition, + popExitTransition: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> ExitTransition?)? = + exitTransition, + sizeTransform: + (@JvmSuppressWildcards + AnimatedContentTransitionScope.() -> SizeTransform?)? = + null, + content: @Composable (AnimatedContentScope) -> Unit +): NavigationDestination = ComposableDestination(id, enterTransition, exitTransition, popEnterTransition, popExitTransition, sizeTransform, content) /** * Helper method for creating inner navigation. + * + * @param id The destination identifier. + * @param destinations The list of inner destinations. */ fun defineDestinationWithInnerNavigation( id: DestinationId<*, *>, @@ -114,6 +179,10 @@ infix fun DestinationId<*, *>.with(destinations: List): N /** * Helper method for creating a dialog [NavigationDestination]. + * + * @param id The destination identifier. + * @param dialogProperties The dialog properties. + * @param content The composable function that will be used to render the content. */ fun defineDialogDestination( id: DestinationId<*, *>, diff --git a/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationView.kt b/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationView.kt index d13c1ccd..8786b315 100644 --- a/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationView.kt +++ b/navigation/src/main/java/no/nordicsemi/android/common/navigation/NavigationView.kt @@ -66,11 +66,11 @@ import no.nordicsemi.android.common.navigation.internal.navigate * * @param destinations The list of possible destinations. * @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 - * @param sizeTransform callback to define the size transform for destinations in this host + * @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 sizeTransform Callback to define the size transform for destinations in this host */ @Composable fun NavigationView( @@ -169,9 +169,14 @@ private fun NavGraphBuilder.create( is ComposableDestination -> { composable( route = destination.id.name, + enterTransition = destination.enterTransition, + exitTransition = destination.exitTransition, + popEnterTransition = destination.popEnterTransition, + popExitTransition = destination.popExitTransition, + sizeTransform = destination.sizeTransform, ) { navigation.use(it.savedStateHandle) - destination.content() + destination.content(this) } } is InnerNavigationDestination -> {