拦截导航UI.onNavDestinationSelected()以使backstack弹出"inclusive = true"



我已经通过navigation_view.setupWithNavController(navController)连接了我的菜单xml和Android导航组件,一切都很完美。我的菜单的一部分是注销选项。如果用户选择此导航目标,则应用应导航到AuthorizationFragment并将后退堆栈弹出到此片段,并将非独占设置为 true以删除所有以前的片段。

我查看了导航库的代码,并达到了应该发生这种情况的点:

NavigationUI.onNavDestinationSelected((:

/**
* Attempt to navigate to the {@link NavDestination} associated with the given MenuItem. This
* MenuItem should have been added via one of the helper methods in this class.
*
* <p>Importantly, it assumes the {@link MenuItem#getItemId() menu item id} matches a valid
* {@link NavDestination#getAction(int) action id} or
* {@link NavDestination#getId() destination id} to be navigated to.</p>
* <p>
* By default, the back stack will be popped back to the navigation graph's start destination.
* Menu items that have <code>android:menuCategory="secondary"</code> will not pop the back
* stack.
*
* @param item The selected MenuItem.
* @param navController The NavController that hosts the destination.
* @return True if the {@link NavController} was able to navigate to the destination
* associated with the given MenuItem.
*/
public static boolean onNavDestinationSelected(@NonNull MenuItem item,
@NonNull NavController navController) {
NavOptions.Builder builder = new NavOptions.Builder()
.setLaunchSingleTop(true)
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim);
if ((item.getOrder() & Menu.CATEGORY_SECONDARY) == 0) {
builder.setPopUpTo(findStartDestination(navController.getGraph()).getId(), false);
}
NavOptions options = builder.build();
try {
//TODO provide proper API instead of using Exceptions as Control-Flow.
navController.navigate(item.getItemId(), null, options);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}

所以我的问题是,是否有办法覆盖此方法并构建将后退堆栈弹出到目标 id 且包含选项设置为 true 的 NavOptions?

像往常一样,睡在问题上会有所帮助。我发现您可以轻松设置自己的NavigationItemSelectedListener.此外,我在问题中提到的方法是公共静态的,因此它也可以很容易地称为回退功能。

这是我的代码:

navigation_view.setNavigationItemSelectedListener { item: MenuItem ->
// check for my special case where I want to pop everything
// from the backstack until we reach the login fragment
if (item.itemId == R.id.fragment_auth) {
val options = NavOptions.Builder()
.setPopUpTo(navController.currentDestination!!.id, true)
.setLaunchSingleTop(true)
.build()
navController.navigate(R.id.action_global_authFragment, null, options)
true // return true -> we handled this navigation event
} else {
// Fallback for all other (normal) cases.
val handled = NavigationUI.onNavDestinationSelected(item, navController)
// This is usually done by the default ItemSelectedListener.
// But there can only be one! Unfortunately.
if (handled) drawer_layout.closeDrawer(navigation_view)
// return the result of NavigationUI call
handled
}
}

最新更新