Android导航组件pop到过渡问题

Android导航组件pop到过渡问题,android,android-architecture-components,android-navigation,android-architecture-navigation,Android,Android Architecture Components,Android Navigation,Android Architecture Navigation,我有两个动作 行动1 <action android:id="@+id/actionBaseFragmentToAskForLocation" app:destination="@+id/introAskForLocationFragment" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnt

我有两个动作

行动1

 <action
        android:id="@+id/actionBaseFragmentToAskForLocation"
        app:destination="@+id/introAskForLocationFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_right" />

行动2

<action
        android:id="@+id/actionIntroAskLocationToLogin"
        app:destination="@id/loginFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left"
        app:popEnterAnim="@anim/slide_in_right"
        app:popExitAnim="@anim/fade_out"
        app:popUpTo="@+id/app_main_navigation" />

我想要的是,当第二个动作被触发时,我想要清除后堆栈,并将仅loginFragment设置为保留在堆栈中

只有一个问题是,当我执行动作2时,“滑出右”作为退出动画执行

我知道如果我们从堆栈中弹出片段,将触发action1的“popExitAnim”,而不是action2的“exitAnim”


但我想知道如何让片段执行滑出左动画以退出,并将其从堆栈中弹出。

这是一个很难解决的问题,因为
NavOptions
在内部由将抽屉绑定到导航图时使用的方便方法处理。我最初使用设置菜单和选项项选择测试了这个解决方案,但是基本思想在这里也应该起作用

首先,确保菜单项ID与导航片段的ID相对应:


...

...
现在,不要使用现成的方法在NavHost活动中实现
NavigationView.OnNavigationItemSelectedListener
,而是像这样覆盖方法
onNavigationItemSelected

@覆盖
公共布尔值onNavigationItemSelected(@NonNull MenuItem item){
NavHost NavHost=Navigation.findNavController(这个,R.id.your_nav_host_片段);
返回NavigationUI.onNavDestinationSelected(项,navHost);
}
这将在图形中作为导航转发所选内容。用设置的片段ID替换
app:defaultNavHost=“true”

您会注意到,虽然这样做有效,但它仍然默认为幻灯片动画。这是因为服务器具有以下设置:

NavOptions.Builder=新的NavOptions.Builder()
.setLaunchSingleTop(真)
.setEnterAnim(R.anim.nav\u默认值\u输入\u动画)
.setExitAnim(R.anim.nav\u default\u exit\u anim)
.setPopEnterAnim(R.anim.nav\u默认值\u弹出\u输入\u动画)
.setPopExitAnim(R.anim.nav\u default\u pop\u exit\u anim);
不幸的是,该方法尚未将
NavOptions.Builder
作为参数,但您可以基于Android源代码创建一个实用程序类来模拟该功能:

公共类NavigationUIHelper{
公共静态布尔值onNavDestinationSelected(@NonNull MenuItem item,
@非空NavController NavController,
@非空NavOptions.Builder){
if((item.getOrder()&Menu.CATEGORY_SECONDARY)==0){
NavDestination=findStartDestination(navController.getGraph());
setPoputto(destination.getId(),false);
}
NavOptions=builder.build();
试一试{
导航(item.getItemId(),null,选项);
返回true;
}捕获(IllegalArgumentException e){
返回false;
}
}
//还需要复制这个私有方法吗
专用静态NavDestination findStartDestination(@NonNull NavGraph graph){
NavDestination startDestination=图形;
while(导航图的startDestination实例){
NavGraph父项=(NavGraph)startDestination;
startDestination=parent.findNode(parent.getStartDestination());
}
返回startDestination;
}
}
最后,在活动中,您现在可以使用NavigationUIHelper中实现的调用替换对NavigationUI的调用:

@覆盖
公共布尔值onNavigationItemSelected(@NonNull MenuItem item){
NavHost NavHost=Navigation.findNavController(这个,R.id.your_nav_host_片段);
NavOptions.Builder=新的NavOptions.Builder()
.setLaunchSingleTop(真)
.setEnterAnim(R.anim.custom_输入)
.setExitAnim(R.anim.custom_出口)
.setPopEnterAnim(R.anim.custom\u pop\u enter)
.setPopExitAnim(R.anim.custom\u pop\u exit);
返回NavigationUIHelper.onNavDestinationSelected(项、导航主机、生成器);
}

这应该允许您根据自己的喜好更改抽屉转换动画,而无需更换导航组件。

我最终覆盖了调用
导航的片段中的
onCreateAnimation
。此示例显示如何按ID导航嵌套导航图,并有条件地替换pop退出动画(或
popExitAnim

override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
    val navController = findNavController()
    val graph = navController.graph.findNode(R.id.onboardingGraph) as NavGraph
    val dest = graph.findNode(R.id.confirmationFragment)
    if (!enter && dest != null && navController.currentDestination?.id == dest.id) {
        return AnimationUtils.loadAnimation(requireContext(), R.anim.slide_out_left)
    }
    return super.onCreateAnimation(transit, enter, nextAnim)
}

请注意,这种特殊情况的部分原因是幻灯片动画的方向性。

我刚刚遇到了同样的问题-您是否设法解决了它/解决了它?似乎是导航组件中的一个错误-我提出了一个错误,结果是重复的。好的,谢谢您提供的信息。如果您不使用动画,popUpTo很好用。但通过动画,我也看到了你所描述的。如果您为作为popUpTo结果而弹出的操作指定了不同的popExitAnim,那么您可以解决这个问题。但你最终打破了正常的后退按钮弹出。所以你赢不了。我希望这个问题很快得到解决。动画是xml集吗?我更新到2.1.0,现在我的浏览器在闪烁(alpha淡入+翻译集)。它看起来不再像集合了,alpha淡入自己就可以了,翻译自己就可以了。我对导航库的状态知之甚少,但我认为他们一定已经在内部解决了这个问题,而这个答案中的代码现在在某些情况下本身就有问题。创建并返回custiom幻灯片动画会导致屏幕闪烁,当我删除
p时,屏幕闪烁消失