片段XXX {}未与片段管理器关联

时间:2019-05-08 13:26:10

标签: android navigation android-jetpack-navigation

我开始在应用程序中使用导航组件,并且遇到以下问题。 我的第一个片段是LoginFragment。成功登录后,将显示mainFragment。我希望当用户位于mainFragment上并按返回按钮时,不要回到loginFragment。为此,我在nav_graph中添加了这两行:app:popUpTo="@+id/lovable_app_navigation"app:popUpToInclusive="true",它很好用。这是我的导航图:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/app_navigation"
  app:startDestination="@id/loginFragment">

  <fragment
    android:id="@+id/loginFragment"
    android:name="com.xxx.LoginFragment"
    android:label="LoginFragment"
    tools:layout="@layout/login_fragment">
    <action
      android:id="@+id/dashboard_action"
      app:destination="@id/mainFragment"
      app:launchSingleTop="true"
      app:popUpTo="@+id/app_navigation"
      app:popUpToInclusive="true"/>
  </fragment>

  <fragment
    android:id="@+id/mainFragment"
    android:name="com.xxx.MainFragment"
    android:label="MainFragment"
    tools:layout="@layout/main_fragment">
       <action
      android:id="@+id/logout_action"
      app:destination="@id/loginFragment"
      app:launchSingleTop="true"
      app:popUpTo="@+id/app_navigation"
      app:popUpToInclusive="true"/>
  </fragment>

  <action
    android:id="@+id/action_global_loginFragment"
    app:destination="@id/loginFragment" />
</navigation>

问题在于,一段时间后,当我的会话到期时,用户在应用程序中的哪个位置,哪个片段中都无所谓,我必须在整个堆栈上显示LoginFragment。我为此action_global_loginFragment创建了一个全局动作。问题是,当我导航到LoginFragment时,出现此错误:

java.lang.IllegalStateException: Fragment LoginFragment{1d6bd24 (829a6832-3480-4bcb-a3f6-7e2ba214d3ca)} not associated with a fragment manager.

如果我删除popUpTopopUpToInclusive可以正常工作,但是后退按钮功能会受到影响,从mainFragment会返回到loginFragment。 任何想法如何解决这个问题? 预先感谢。

5 个答案:

答案 0 :(得分:8)

我遇到了同样的问题,我设法通过将navigate方法包装在view?.post调用中来解决了这个问题,

view?.post {
    findNavController().navigate(SplashFragmentDirections.actionSplashFragmentToLoginFragment())
}

答案 1 :(得分:1)

当您尝试在已分离的片段上调用findNavController()时,会导致此问题,如果您使用的是Kotlin,则可以像这样创建扩展功能

fun Fragment.findNavControllerSafely(): NavController? {
    return if (isAdded) {
        findNavController()
    } else {
        null
    }
}

然后在任何片段中使用它

findNavControllerSafely()?.navigate(/*pass here the nav directions>*/)

您也可以在try / catch周围加上它,但我不建议您这样做,因为它会静默地捕获/忽略其他可能有用的异常,请尝试浏览findNavController()的源代码以更好地了解引发的异常类型

答案 2 :(得分:0)

我也遇到了这个问题,很难知道怎么了!

我发现此网址对我有很大帮助!:Android Navigation Component Issue 由于当将findNavController()与非NavHostFragment或不在NavHostFragment内的片段一起使用时,此家伙建议在每个片段上创建一个函数。

fun Fragment.getFragmentNavController(@IdRes id: Int) = activity?.let {
    return@let Navigation.findNavController(it, R.id)
}

然后,您可以将所有具有ID的导航实例都如下所示:

getFragmentNavController(R.id.shipping_host_nav).navigate(R.id.id_of_host_nav)

答案 3 :(得分:0)

对我来说,问题是由于配置更改而恢复后的片段是片段管理器在片段中无效,所以我必须直接从这样的活动中获取它:

activity?.findNavController(R.id.nav_host_fragment)?.navigate(....)

activity?.supportFragmentManager?.setFragmentResultListener(.....)

答案 4 :(得分:0)

我今天遇到了同样的问题。 问题在于导入了错误的文件。 实际上可以导入 3 个文件。

  1. 导入 androidx.navigation.fragment.findNavController

    这是 findNavController()

  2. 导入 androidx.navigation.Navigation.findNavController

    这表示 findNavController(Activity, Int)

  3. 导入 androidx.navigation.fragment.NavHostFragment.findNavController

    这是 findNavController(Fragment)

如果我使用了第二个,它会给出一个错误 Fragment not attach/ associated with/to an Activity。 (不记得确切的错误)

如果我使用第三个,我会遇到与@Gabrielle 相同的错误

所以,对我来说,第一个工作得非常好,因为它不需要 Activity 或 Fragment。