3

I have an activity (main) with three fragments (first, second and third). I included the 3 fragments in my activity (activity_main.xml) by using <include layout="@layout/content_main"/>. The content_main.xml is using FragmentContainerView with id = nav_host_fragment. And this is my nav_graph.xml:

<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/nav_graph"
    app:startDestination="@id/FirstFragment">

    <fragment
        android:id="@+id/FirstFragment"
        android:name="com.example.makegroups.FirstFragment"
        android:label="@string/first_fragment_label"
        tools:layout="@layout/fragment_first">

        <action
            android:id="@+id/action_FirstFragment_to_SecondFragment"
            app:destination="@id/SecondFragment" />
    </fragment>

    <fragment
        android:id="@+id/SecondFragment"
        android:name="com.example.makegroups.SecondFragment"
        android:label="@string/second_fragment_label"
        tools:layout="@layout/fragment_second">

        <action
            android:id="@+id/action_SecondFragment_to_FirstFragment"
            app:destination="@id/FirstFragment" />
        <action
            android:id="@+id/action_SecondFragment_to_ThirdFragment"
            app:destination="@id/ThirdFragment" />
    </fragment>

    <fragment
        android:id="@+id/ThirdFragment"
        android:name="com.example.makegroups.ThirdFragment"
        android:label="@string/third_fragment_label"
        tools:layout="@layout/fragment_third">

        <action
            android:id="@+id/action_ThirdFragment_to_FirstFragment"
            app:destination="@id/FirstFragment" />
    </fragment>
</navigation>

I have a floatingactionbuttonin my activity (first fragmentstarts first) and when I click on it, I open the third fragment. On the third fragment I have a button (next) to navigate to the first fragment, and when I click on it, I am back to first fragment using:

Fragment frg = new FirstFragment();
FragmentManager fm = requireActivity().getSupportFragmentManager();

Now (while I am in the first fragment), I click on the button next(another button to navigate to the second fragment), then the app crashes. I found this error:

java.lang.IllegalStateException: View androidx.constraintlayout.widget.ConstraintLayout{c9572fa V.E...... ........ 0,0-1440,2112} does not have a NavController set

Why I am getting this error? -I tried these suggestions here, without success.

I am using Java.

EDIT: Read the last comment with @Zain to know why I got the error.

Zain
  • 37,492
  • 7
  • 60
  • 84
carl
  • 388
  • 2
  • 19
  • check this may be it will help you https://github.com/sunil-singh-chaudhary/Fragment-Nested-Child-Backpress – Sunil Chaudhary Dec 17 '20 at 10:11
  • If you are in the first fragment and need to go to second fragment just this should work: findNavController().navigate(R.id. action_FirstFragment_to_SecondFragment) – ACR Dec 17 '20 at 12:46

4 Answers4

2

Bu using Navigation Architecture components, The NavController is the responsible for fragment transaction and managing the back stack instead of the Support FragmentManager.

So, instead of making tranditional framgnet transactions with FragmentManager

You can move from ThridFragment to the first one by:

 Navigation.findNavController(requireView()).navigate(R.id.action_ThirdFragment_to_FirstFragment);

Where action_ThirdFragment_to_FirstFragment is the id of the action you defined in the navigation graph to move from ThridFragment to FirstFragment

UPDATE:

As discussed from comments, besides replacing FragmentManager by NavController in all actions; there is another issue:

Missing of action_FirstFragment_to_ThirdFragment action from the navigation graph.

Zain
  • 37,492
  • 7
  • 60
  • 84
  • I tried it, but I am getting the same error. Remember that I am in `the first fragment` and want to go to the `second fragment`. I tried this too: `NavHostFragment.findNavController(FirstFragment.this).navigate(R.id.action_FirstFragment_to_SecondFragment);` – carl Dec 17 '20 at 09:51
  • I see, let me check it – Zain Dec 17 '20 at 09:57
  • I tried what you suggested on moving from `3th` to `1st`, but it doesn't work. Therefore I tried with `FragmentManager`. But know I want to use/learn the `NavController`. I simply could not. – carl Dec 17 '20 at 10:08
  • @carl now when you launch the app, `FirstFrag > SecondFrag` (no issues in this), but `FirstFrag > ThirdFrag > FirstFrag > SecondFrag` (the issue is here) right ? – Zain Dec 17 '20 at 10:30
  • app starts. can move from `1` to `2`, `2` to `1 back to `2` and from `2` to `3` and `3` to `1`. All of these without issues. When I click on the `floatingactionbutton` to move `1` > `3`, it's ok (using `FragmentManager`). But issues starts from here, cannot `3` > `1` (had to use `FragmentManager`) – carl Dec 17 '20 at 10:41
  • Not sure if [this](https://stackoverflow.com/questions/60962539/constraintlayout-does-not-have-a-navcontroller-set-for-item-clicked-on-recyclerv) can give some clues.. I can't see other mistakes in your provided code – Zain Dec 17 '20 at 11:00
  • It's not related to my problem. I replaced every `NavHostFragment.findNavController(fragment) .navigate(R.id.action_...);` to a `fragmentManager` and everything is ok. I don't know why this issue with `NavController`!!!! – carl Dec 17 '20 at 11:12
  • 1
    I accepted your answer because you was on the right track. My problem was: I FORGOT TO PUT ONE ACTION. See my `nav_graph.xml`. I forgot `action_FirstFragment_to_ThirdFragment`. Therefore I had to use `FragmentManager` and the issues started. Now I can navigate through all the fragments using `NavController`. – carl Dec 17 '20 at 13:59
  • Thanks @carl.. I will update it in the answer so it may help some body else around the globe.. Happy coding – Zain Dec 17 '20 at 14:25
1
navController = Navigation.findNavController(activity, R.id.nav_host_fragment)
Arda Kazancı
  • 8,341
  • 4
  • 28
  • 50
  • I am in a `fragment` the `first fragment`. I cannot used what you suggest. I tried this: `NavHostFragment.findNavController(FirstFragment.this).navigate(R.id.action_FirstFragment_to_SecondFragment);`, but I am getting the same rror. – carl Dec 17 '20 at 09:45
0

when using the Navigation Component you should not handle the transactions yourself, instead you define the actions between each fragment and then access those directly like this

override fun onCreate(){
  val navController = this.findNavController()
  button.setOnClickListener{
     navController.navigate(R.id.action_FirstFragment_to_SecondFragment, null)
  }
}

and your nav_graph should be like this

<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/nav_graph"
app:startDestination="@id/FirstFragment">

<fragment
    android:id="@+id/FirstFragment"
    android:name="com.example.makegroups.FirstFragment"
    android:label="@string/first_fragment_label"
    tools:layout="@layout/fragment_first">

    <action
        android:id="@+id/action_FirstFragment_to_SecondFragment"
        app:destination="@id/SecondFragment" />
</fragment>

<fragment
    android:id="@+id/SecondFragment"
    android:name="com.example.makegroups.SecondFragment"
    android:label="@string/second_fragment_label"
    tools:layout="@layout/fragment_second">

    <action
        android:id="@+id/action_SecondFragment_to_FirstFragment"
        app:destination="@id/FirstFragment" />
    <action
        android:id="@+id/action_SecondFragment_to_ThirdFragment"
        app:destination="@id/ThirdFragment" />
</fragment>

<fragment
    android:id="@+id/ThirdFragment"
    android:name="com.example.makegroups.ThirdFragment"
    android:label="@string/third_fragment_label"
    tools:layout="@layout/fragment_third">

    <action
        android:id="@+id/action_ThirdFragment_to_FirstFragment"
        app:destination="@id/FirstFragment" />
</fragment>
Mahmoud Omara
  • 533
  • 6
  • 22
  • You are using `Kotlin`. I don't want to handle the transactions by myself. I had to do it (it's not working for me!). And what is `findNavController()`?. The `nav_graph` you showed it's the same as mine. – carl Dec 17 '20 at 12:09
  • I can use `NavHostFragment.findNavController(FirstFragment.this) .navigate(R.id.action_FirstFragment_to_SecondFragment);`, but it dosen't work for me. – carl Dec 17 '20 at 12:23
  • 1
    my bad, u should add this.findNavController(), will edit it in the answer, and yes nav graph is the same as yours cuz it is correct – Mahmoud Omara Dec 17 '20 at 12:45
  • your `findNavContoller()` implemented like this:`public static NavController findNavController(@NonNull Fragment fragment) { View view = fragment.getView(); if (view != null) { return Navigation.findNavController(view); } return null; }` – carl Dec 17 '20 at 13:05
  • could you write that in your question? don't write code in comments – Mahmoud Omara Dec 17 '20 at 13:35
0
val navController = Navigation.findNavController(requireActivity(), R.id.fragment_container)
navigate.navigate(R.id.fragment)
patrick.elmquist
  • 2,113
  • 2
  • 21
  • 35
fazal ur Rehman
  • 330
  • 2
  • 5