Search code examples
androidandroid-fragmentsandroid-navigationandroid-architecture-navigationandroid-navigation-graph

Why Android Navigation Component screen not go back to previous Fragment,but a method in onViewCreated of previos Fragment being called?


I have 2 fragment call CreateRoomFragment and DisplayPhotoFragment,the navigation graph is look like this:

<navigation>    
<fragment
    android:id="@+id/createRoomFragment"
    android:name="package.room.CreateRoomFragment"
    android:label="Create a room"
    tools:layout="@layout/fragment_create_room">
    <action
        android:id="@+id/action_createRoomFragment_to_roomFragment"
        app:destination="@id/roomFragment" />
    <action
        android:id="@+id/action_createRoomFragment_to_displayPhotoFragment"
        app:destination="@id/displayPhotoFragment" />
</fragment>

<fragment
    android:id="@+id/displayPhotoFragment"
    android:name="package.fragment.DisplayPhotoFragment"
    android:label="fragment_display_photo"
    tools:layout="@layout/fragment_display_photo" >
    <argument android:name="bitmap"
              app:argType="android.graphics.Bitmap"/>
</fragment>

So when I wanna to move from CreateRoomFragment to DisplayPhotoFragment,I use the do as below:

NavDirections action = CreateRoomFragmentDirections.actionCreateRoomFragmentToDisplayPhotoFragment(selectedPhoto);
Navigation.findNavController(view).navigate(action);

Doing this,I can navigate to DisplayPhotoFragment.

But when I press back button of the device and also the Back arrow from the toolbar,it cant go back to CreateRoomFragment.

I tried this,but still unable to back to previous fragment:

requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(),
                new OnBackPressedCallback(true) {
                    @Override
                    public void handleOnBackPressed() {

                       navController.navigateUp();  //I tried this 
                       navController.popBackStack(R.id.createRoomFragment,false); //and also this
                    }
                });

Main Problem now:

By using the code above,the screen didnt go back to previous Fragment(CreateRoomFragment).It still stuck in DisplayPhotoFragment,but at the same time,an API method in CreateRoomFragment onViewCreated section is being called.

What causing this? and how can I solve this problem?


Solution

  • Android maintains a back stack that contains the destinations you've visited. The first destination of your app is placed on the stack when the user opens the app. Each call to the navigate() method puts another destination on top of the stack. Tapping Up or Back calls the NavController.navigateUp() and NavController.popBackStack() methods, respectively, to remove (or pop) the top destination off of the stack.

    NavController.popBackStack() returns a boolean indicating whether it successfully popped back to another destination. The most common case when this returns false is when you manually pop the start destination of your graph.

    When the method returns false, NavController.getCurrentDestination() returns null. You are responsible for either navigating to a new destination or handling the pop by calling finish() on your Activity.

    When navigating using an action, you can optionally pop additional destinations off of the back stack by using popUpTo and popUpToInclusive parameter of the action.

    class MyFragment : Fragment() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val onBackPressedCallback = object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                    if (true == conditionForCustomAction) {
                        CustomActionHere()
                    } else  NavHostFragment.findNavController(this@MyFragment).navigateUp();    
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(
            this, onBackPressedCallback
        )
        ...
    }