Jetpack navigation 3 is now stable, and I am learning how to work with this type of navigation. One thing I'm missing is the AnimatedContentScope of shared elements using navigation. In navigation 2, the AnimatedContentScope can be retrieved by accessing the property within a composable<T> extension or a dialog<T> extension of NavGraphBuilder.
My libs.versions.toml
[versions]
navigation2 = "2.9.6"
navigation3 = "1.0.0"
# Other libraries versions here
[libraries]
androidx-navigation2 = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation2" }
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "navigation3" }
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "navigation3" }
# Other libraries here
[plugins]
# My plugins here
Nav 2 scheme
This is my existing code using nav 2 that works correctly with the shared elements animation:
AppNavHost.kt
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun AppNavHost() {
SharedTransitionLayout {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = DashboardNavRoute,
) {
dashboard(
navController = navController,
sharedTransitionScope = this@SharedTransitionLayout
)
// Other routes
}
}
}
DashboardRoot.kt
As you can see, here I pass the property animatedContentScope to my screen using the scope of the composable<T>
@OptIn(ExperimentalSharedTransitionApi::class)
fun NavGraphBuilder.dashboard(
navController: NavController,
sharedTransitionScope: SharedTransitionScope,
) {
composable<DashboardNavRoute> {
val viewModel = hiltViewModel<DashBoardViewModel>()
val state by viewModel.uiState.collectAsState()
val snackbarHostState = remember { SnackbarHostState() }
// Other composables
DashboardScreen(
onEvent = viewModel::onEvent,
state = state,
snackbarHostState = snackbarHostState,
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = this,
)
}
}
DashboardScreen.kt
@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
@Composable
internal fun DashboardScreen(
snackbarHostState: SnackbarHostState,
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope,
onEvent: (DashboardUiEvent) -> Unit,
state: DashboardUiState,
) {
// Screen content here
}
Nav 3 scheme
I'm migrating to nav 3 and right now I have something like:
AppNavDisplay.kt
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun AppNavDisplay() {
SharedTransitionLayout {
val backStack = rememberNavBackStack(DashboardNavRoute)
NavDisplay(
backStack = backStack,
entryProvider = entryProvider {
dashboardEntry(
backStack = backStack,
sharedTransitionScope = this@SharedTransitionLayout
)
// Other entries
}
)
}
}
DashboardRoot.kt
@OptIn(ExperimentalSharedTransitionApi::class)
fun EntryProviderScope<NavKey>.dashboardEntry(
backStack : NavBackStack<NavKey>,
sharedTransitionScope: SharedTransitionScope,
) {
entry<DashboardNavRoute> {
val viewModel = hiltViewModel<DashBoardViewModel>()
val state by viewModel.uiState.collectAsState()
val snackbarHostState = remember { SnackbarHostState() }
// Other composables
DashboardScreen(
onEvent = viewModel::onEvent,
state = state,
snackbarHostState = snackbarHostState,
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = this,
)
}
}
In the line: animatedContentScope = this,, I have the following syntax error:
Argument type mismatch: actual type is 'EntryProviderScope', but 'AnimatedContentScope' was expected.
Question
Is there a way to get this AnimatedContentScope inside the scope of EntryProviderScope<NavKey> or in any other scope in the context of nav 3?