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

Posted

技术标签:

【中文标题】导航到目的地时仅创建一个片段实例(android)【英文标题】:Create only one instance of fragment while navigating to destinations(android) 【发布时间】:2020-07-10 15:09:36 【问题描述】:

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

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

寻找解决方案。

谢谢。

【问题讨论】:

请添加更多关于您所问内容的详细信息。添加一些代码以显示您已编程的内容或添加可能有用的图片。这样你就更有可能得到问题的答案。 我添加了代码。如果还不够,请告诉我应该添加什么代码。 您好,您是否找到了添加片段实例的方法? 你好,是的,我猜我覆盖了乐趣 onNavigationItemSelected(item: MenuItem): 主要活动中的布尔值并使用了导航选项。 val navBuilder = NavOptions.Builder() val navOptions = navBuilder.setPopUpTo(item.itemId, true).build() 【参考方案1】:

我遇到了同样的问题,但不幸的是,以前的解决方案对我不起作用,尽管它们应该可以解决问题。谢谢顺便说一句! :)

这对我有用,适应你的代码是:

findNavController().navigate(
    RequestTransferFragmentDirections.actionRequestTransferFragmentToBlankFragment()),
    NavOptions.Builder().setLaunchSingleTop(true).build()
)

我在navigate() 文档中看到我们可以传递options,因此通过传递NavOptions.Builder().setLaunchSingleTop(true).build() 将创建此类片段的单个实例。

【讨论】:

【参考方案2】:

我在这种模式下只实现了一个片段类型实例的请求:

在 navigation_graph.xml 我声明了一个 popUp-action 到 fragment-destination

<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)

【讨论】:

【参考方案3】:

在这里回答是因为我有同样的问题。以下是对我有用的解决方案。我最终使用了导航控制器并弹出到一个 backstack 目的地,如果它存在,如果它不存在,那么我正常导航到它。

看起来像这样:

if ( ! nav.popBackStack(R.id.action_profile, false)) 
    nav.navigate(R.id.action_profile)

nav.popBackStack(R.id.action_profile, false)如果传入的目标不在backstack中,则返回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();
    

【讨论】:

【参考方案4】:

你可以这样做:

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()

导航到该目的地

【讨论】:

以上是关于导航到目的地时仅创建一个片段实例(android)的主要内容,如果未能解决你的问题,请参考以下文章

Android Jetpack Navigation:如何在 OnNavigatedListener 中获取目的地的片段实例?

从另一个图表导航到片段,而不是起始目的地

Android导航组件后退按钮不起作用

Jetpack 导航到一个共同的目的地

Android Jetpack导航,另一个主机片段内的主机片段

使用Android导航组件时如何从后台获取片段?