0

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?

1
  • Please edit the question to replace your code with a minimal reproducible example that we can actually execute. Commented Nov 22 at 13:46

1 Answer 1

4

Navigation3 provides the AnimatedContentScope in LocalNavAnimatedContentScope composition local, so you can simply do

entry<DashboardNavRoute> {
    DashboardScreen(
        animatedContentScope = LocalNavAnimatedContentScope.current,
    )
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.