我正在使用导航组件。导航时,我不想创建新的片段实例(如果片段实例已存在于后堆栈中,则弹出该片段的前面存在)。
findNavController().navigate(RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment())
神魂颠倒,找到解决办法。
谢谢。
答案 0 :(得分:4)
我在这种模式下只实现了一个片段类型实例的请求:
在 navigation_graph.xml 中,我向片段目标声明了一个弹出操作
<action
android:id="@+id/home_action"
app:destination="@id/my_dest"
app:popUpTo="@id/my_dest"
app:popUpToInclusive="true" />
<fragment
android:id="@+id/my_dest"
android:name="com.project.android.fragments.MyFragment"
android:label=""
tools:layout="@layout/my_fragment_layout" />
在代码中我调用操作
navController.navigate(R.id.home_action)
答案 1 :(得分:2)
我也遇到了同样的问题,但是不幸的是,尽管以前的解决方案应该可以解决该问题,但对我来说却并不奏效。谢谢顺便说一句! :)
这对我有用,适合您的代码为:
findNavController().navigate(
RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment()),
NavOptions.Builder().setLaunchSingleTop(true).build()
)
我在navigate()文档中看到,我们可以传递options,因此通过传递NavOptions.Builder().setLaunchSingleTop(true).build()
将创建此类片段的单个实例。
答案 2 :(得分:1)
您可以执行以下操作:
bottomNavigation.setupWithNavController(navController)
bottomNavigation.setOnNavigationItemSelectedListener {
if (it.itemId == R.id.navigation_home) {
navController.popBackStack(R.id.navigation_home, false)
true
}
else
NavigationUI.onNavDestinationSelected(it , navController)
}
使用上面的代码,只要用户单击底部导航视图中的 Home (R.id.navigation_home)项目,该应用程序便会导航回 Home的现有实例使用 popBackStack()。
如果选择项在底部导航中选择了另一个目的地,则该应用将使用 NavigationUI.onNavDestinationSelected()
导航到该目的地。答案 3 :(得分:0)
在这里回答,因为我有同样的问题。以下是对我有用的解决方案。我最终使用了nav控制器,然后弹出到后退目标(如果存在),如果不存在,那么我通常会导航到它。
这看起来像这样:
if ( ! nav.popBackStack(R.id.action_profile, false)) {
nav.navigate(R.id.action_profile)
}
如果传入的目的地不在堆栈中,则 nav.popBackStack(R.id.action_profile, false)
将返回false,否则将弹出并返回true。布尔值也用于弹出目标片段。
从文档中
/**
* Attempts to pop the controller's back stack back to a specific destination.
*
* @param destinationId The topmost destination to retain
* @param inclusive Whether the given destination should also be popped.
*
* @return true if the stack was popped at least once and the user has been navigated to
* another destination, false otherwise
*/
public boolean popBackStack(@IdRes int destinationId, boolean inclusive) {
boolean popped = popBackStackInternal(destinationId, inclusive);
// Only return true if the pop succeeded and we've dispatched
// the change to a new destination
return popped && dispatchOnDestinationChanged();
}