androidandroid-jetpack-composejetpack-compose-navigationjetpack-compose-accompanist

Jetpack Navigation Compose Animation incorrect pop animation


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.


Solution

  • 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