Jetpack Navigation Compose Animation incorrect pop animation

2.9k Views Asked by At

I use the library from the Accompanist Jetpack Navigation Computer Animation, when I press the back button, the animation I prescribed is not performed, but some other strange one. Video with animation

AnimatedNavHost(navController = navController,
        startDestination = categoryScreenRoute,
        enterTransition = {
            slideIntoContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        exitTransition = {
            slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        popEnterTransition = {
            slideIntoContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        },
        popExitTransition = {
            slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        })
    {
        composable(route = categoryScreenRoute) {
            CategoryScreen(navController = navController, viewModel = viewModel)
        }
        composable(route = itemsScreenRoute) {
            ItemsScreen(navController = navController, viewModel = viewModel)
        }
    }

I tried to prescribe an animation for each composable function, completely removed the animation of the transition back.

1

There are 1 best solutions below

5
On BEST ANSWER

define an extension method

fun NavGraphBuilder.setComposable(
    route: String,
    arguments: List<NamedNavArgument> = emptyList(),
    deepLinks: List<NavDeepLink> = emptyList(),
    content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit){
    return composable(
        route = route,
        arguments = arguments,
        deepLinks = deepLinks,
        enterTransition = {
           slideIntoContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        exitTransition = {
           slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Left, animationSpec = tween(speedAnimation)
            )
        },
        popEnterTransition = {
           slideIntoContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        },
        popExitTransition = {
             slideOutOfContainer(
                AnimatedContentScope.SlideDirection.Right, animationSpec = tween(speedAnimation)
            )
        },
        content = content
    )
}

The method of use is as follows:

AnimatedNavHost(navController = navController, startDestination = categoryScreenRoute) {
        setComposable(route = categoryScreenRoute) {
            CategoryScreen(navController = navController, viewModel = viewModel)
        }
        setComposable(route = itemsScreenRoute) {
            ItemsScreen(navController = navController, viewModel = viewModel)
        }
    }

Your CategoryScreen Example:

@Composable
fun CategoryScreen(viewModel: CategoryViewModel = hiltViewModel(), navController: NavController) {
    val categoryState by remember { viewModel.getAllCategory() }

    Box(modifier = Modifier.fillMaxSize()) {
        when (categoryState) {
            is ApiResult.Error -> {
                Text(
                    text = (categoryState as ApiResult.Error<List<Category>>).message.toString(),
                    modifier = Modifier.padding(16.dp),
                    fontSize = 24.sp,
                    fontWeight = FontWeight.W600
                )
            }
            is ApiResult.Exception -> {
                Text(
                    text = (categoryState as ApiResult.Exception<List<Category>>).e,
                    modifier = Modifier.padding(16.dp),
                    fontSize = 24.sp,
                    fontWeight = FontWeight.W600
                )
            }
            is ApiResult.Success -> {
                val list = (categoryState as ApiResult.Success).data

                LazyVerticalGrid(columns = GridCells.Fixed(2), contentPadding = PaddingValues(16.dp)) {
                    items(list) { category ->
                        CategoryItem(category) {
                            viewModel.selectCategory(category)
                            navController.navigateToItemsScreen()
                        }
                    }
                }
            }
        }
    }
}

enter image description here