导航到目的地时仅创建一个片段实例(android)

时间:2020-03-30 09:12:26

标签: android android-studio android-fragments navigation navigationcontroller

我正在使用导航组件。导航时,我不想创建新的片段实例(如果片段实例已存在于后堆栈中,则弹出该片段的前面存在)。

    findNavController().navigate(RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment())

神魂颠倒,找到解决办法。

谢谢。

4 个答案:

答案 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)
}

enter image description here

使用上面的代码,只要用户单击底部导航视图中的 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();
    }