如何删除 Jetpack Compose Navigation 中的默认过渡

Sor*_*tfi 14 android android-jetpack-navigation android-jetpack-compose

我使用以下代码片段从一个可组合项导航到另一个可组合项,但它有一个默认的淡入淡出动画。我怎样才能删除它?我尝试使用空anim资源,但它不起作用。

navHostController.navigate(
    "destination_route",
    navOptions {
        popUpTo("this_route") {
            inclusive = true
        }
        anim {
            enter = R.anim.empty_animation
            exit = R.anim.empty_animation
            popEnter = R.anim.empty_animation
            popExit = R.anim.empty_animation
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

R.anim.empty_animation:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--Empty to disable animation-->
</set>
Run Code Online (Sandbox Code Playgroud)

Daf*_*afi 12

如果您使用版本或以上版本navigation-compose:2.7.5,则需要enterTransition在.exitTransitionNavHost

NavHost(navController = rememberNavigationBarController,
        startDestination = "home",
        modifier = Modifier.padding(it),
        enterTransition = {
            // you can change whatever you want transition
            EnterTransition.None 
        },
        exitTransition = {
            // you can change whatever you want transition
            ExitTransition.None
        }) {
        composable("home") {}
        composable("cinema") {}
        composable("ticket") { }
    }
Run Code Online (Sandbox Code Playgroud)


V M*_*can 6

更新导航 2.7+

正如其他人所提到的,导航库现在使我们能够通过EnterTransition.None和禁用默认的淡入淡出过渡ExitTransition.None。这是一种更简洁的方法,应该优于我提出的选项。

话虽如此,有些用例只能由原始答案中的解决方案来处理。转换None使得相关屏幕立即出现/消失。不幸的是,它们不提供与可能正在进行的其他转换的同步。以这个场景为例,我们有一个屏幕B,我们想要向上滑动到另一个屏幕上A。如果我们使用ExitTransition.Noneon screen ,一旦动画开始, Ascreen 的内容就会消失(即使 screen还没有扩展到全屏),从而减弱了想要的效果。在这种情况下,除了使用原始答案中的解决方案之外,没有其他方法:使用与过渡具有相同持续时间的“假”过渡,以确保屏幕在我们需要的时间内保持可见。Aslide-upBslide-up

答案

截至 2023 年,似乎仍然无法删除默认crossfade动画。但是,您可以通过使用类似以下内容来非常接近:

val noEnterTransition : AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
    fadeIn(
        animationSpec = tween(durationMillis = 300),
        initialAlpha = 0.99f
    )
}

val noExitTransition : AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
    fadeOut(
        animationSpec = tween(durationMillis = 300),
        targetAlpha = 0.99f
    )
}
Run Code Online (Sandbox Code Playgroud)

自定义过渡从不100%透明度淡出到99%整个动画持续时间(肉眼无法察觉)。

唯一需要注意的是,durationMillis动画结束后,屏幕将完全消失。因此,如果您需要它保持可见时间更长(如果您有一个长输入动画来替换当前动画composable),则需要增加动画duration的。因此,请选择满足您需求的最小值(因为我们希望避免不必要的插值)。durationopacity

希望这可以帮助!


Epi*_*rce 1

目前,无法在 Navigation-Compose 当前版本(2.4.0-beta02)提供的 NavHost 中配置动画。

@Composable
public fun NavHost(
    navController: NavHostController,
    graph: NavGraph,
    modifier: Modifier = Modifier
) {
    val backStackEntry = visibleTransitionsInProgress.lastOrNull() ?: visibleBackStack.lastOrNull()

    var initialCrossfade by remember { mutableStateOf(true) }
    if (backStackEntry != null) {
        // while in the scope of the composable, we provide the navBackStackEntry as the
        // ViewModelStoreOwner and LifecycleOwner
        Crossfade(backStackEntry.id, modifier) { //// <<----- this 
Run Code Online (Sandbox Code Playgroud)

由于Crossfade不可配置,因此无法更改转换。

要改变动画,你必须放弃使用NavHostNavigation-Compose提供的。