在 Android 上获取 jetpack 可组合导航中的上一页来管理页面进入/退出动画

问题描述 投票:0回答:1

我希望同一页面有不同的导航动画,但针对不同的导航场景。例如

  • page4 -> page1 - 第一个动画。
  • 第 5 页 -> 第 1 页 - 第二个动画。

实际场景例如page1 是底部NavigationBar 中的页面之一。 page5是从page1更新一些属性的页面。我想通过使用不同的导航动画来强调,第 1 页是主要的,第 5 页是次要的。

所以我面临以下问题。我找不到可靠的解决方案来获取“上一页”和“下一页”页面名称。下面的代码块是带有条件运算符的 page1 的 EnterTransition,以支持基于上一页名称的不同动画。

enterTransition = { //enterTransition for page1
                when("previousPageName") {
                    "page1" ->   fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
                    "page2" ->  fadeIn() + slideInHorizontally()
                    else ->  fadeIn()
                }

            }

要获取上一页的名称,显然,最好的方法是使用NavigationController,因此可以重写上面的示例。

enterTransition = {  //enterTransition for page1
                when(**navController.previousBackStackEntry!!.destination.route**) {
                    "page1" ->   fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
                    "page2" ->  fadeIn() + slideInHorizontally()
                    else ->  fadeIn()
                }

            }

我希望随时在那里找到上一页的名称。但实际上,在使用 navigationController.popUpBackStack() 完成导航的情况下,例如单击“返回”按钮。它删除/破坏 navController.previousBackStackEntry 并因此包含一个我不期望的页面,例如“第3页”。我可以理解这种行为,它与 BackStack 一起运行,但如果是这样,我不知道如何根据导航图状态管理不同页面之间的不同动画。一种可能的解决方案是拥有/管理一个变量来存储上一页,但这是我用来实现我的目标的最后一个。找到更优雅的解决方案会很高兴。

所以我有几个问题:

  1. 有没有通用的解决方案可以根据导航场景为一个页面设置不同的进入/退出动画?
  2. 获取上一页的最佳方式是什么并且不用担心
    popUpBackStack()
navController.navigate("page1") {
                            popUpTo(
                                "page5"
                            ) { inclusive = true }
                        }

提前感谢您的帮助。

尝试从 navigationController.previousBackStackEntry 获取上一页,但没有所需的结果

android animation navigation android-jetpack-compose composable
1个回答
0
投票

Navigation Compose 中的动画中所述,每个转换 lambda 的格式为:

enterTransition: (
    AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition?
)? = null,

正如它所解释的:

该 lambda 使用

AnimatedContentScope
为您提供
NavBackStackEntry
,即您来自哪里(
initialState
)和要去哪里(
targetState
)。例如,对于
enterTransition
,输入的目的地是
targetState
— 您要应用
enterTransition
的目的地。

它可以让您编写代码,例如:

enterTransition = {
    // initialState is the screen you are coming from (the one leaving)
    // targetState is the screen you are going to (the one entering)
    when(initialState.destination.route) {
        "page1" ->   fadeIn(animationSpec = tween(delayMillis = 250)) + slideInHorizontally(initialOffsetX = {-it}, animationSpec = tween(delayMillis = 150, durationMillis = 200))
        "page2" ->  fadeIn() + slideInHorizontally()
        else ->  fadeIn()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.