Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment XXX {} not associated with a fragment manager

I started using navigation component in my application and I am facing with the following problem. My first fragment is LoginFragment. After a success login, the mainFragment is displayed. I want that when user is on mainFragment and press back button to not go back to loginFragment. For this I added these 2 lines in nav_graph : app:popUpTo="@+id/lovable_app_navigation" and app:popUpToInclusive="true" and it works well. Here is my navigation graph :

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

The problem is that after a time, when my session expires, it doesn't matter where the user is in application, in which fragment, I must to display the LoginFragment over the all stack. I created a global action for this action_global_loginFragment. The problem is that when I navigate to LoginFragment I get this error :

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

If I remove popUpTo and popUpToInclusive it works fine, but then the back button functionality is affected, from mainFragment it goes back to loginFragment. Any idea how to fixed this? Thanks in advance.

like image 699
Gabrielle Avatar asked May 08 '19 13:05

Gabrielle


2 Answers

The same issue was happening to me, I managed to solve it by wrapping the navigate method inside a view?.post call like so:

view?.post {
    findNavController().navigate(SplashFragmentDirections.actionSplashFragmentToLoginFragment())
}
like image 61
Joscplan Avatar answered Nov 11 '22 04:11

Joscplan


The problem is caused when you try to call findNavController() on a fragment that has been detached, if you're using Kotlin you can create an extension function like so

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

then use it in any fragment

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

you can also surround it with try/catch but I do not recommend this as it will silently catch/ignore other exceptions that might be useful, try navigating through the source code of findNavController() to get a better feel of the kind of exceptions that are thrown

like image 43
Mohamed Eleish Avatar answered Nov 11 '22 05:11

Mohamed Eleish