How to clear navigation Stack after navigating to another fragment in Android

末鹿安然 提交于 2019-11-27 11:33:05
Subhojit Shaw

First, add attributes app:popUpTo='your_nav_graph_id' and app:popUpToInclusive="true" to the action tag.

<fragment
    android:id="@+id/signInFragment"
    android:name="com.glee.incog2.android.fragment.SignInFragment"
    android:label="fragment_sign_in"
    tools:layout="@layout/fragment_sign_in" >
    <action
        android:id="@+id/action_signInFragment_to_usersFragment"
        app:destination="@id/usersFragment"
        app:launchSingleTop="true"
        app:popUpTo="@+id/main_nav_graph"
        app:popUpToInclusive="true" />
</fragment>

Second, navigate to the destination, using above action as parameter.

findNavController(fragment).navigate(
     SignInFragmentDirections.actionSignInFragmentToUserNameFragment())

See the docs for more information.

NOTE: If you navigate using method navigate(@IdRes int resId), you won't get the desired result. Hence, I used method navigate(@NonNull NavDirections directions).

NOTE: Clear task is deprecated, official description is

This method is deprecated. Use setPopUpTo(int, boolean) with the id of the NavController's graph and set inclusive to true.

Old Answer

If you don't wanna go through all that fuzz in code, you can simply check Clear Task in Launch Options in properties of the action.

Edit: As of Android Studio 3.2 Beta 5, Clear Task is no longer visible in Launch Options window, but you can still use it in navigation's XML code, in action tag, by adding

app:clearTask="true"

I finally figure it out thanks to How to disable UP in Navigation for some fragment with the new Navigation Architecture Component?

I had to specify .setClearTask(true) as a NavOption.

mAuth.signInWithCredential(credential)
            .addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "signInWithCredential:success");


                        NavOptions.Builder navBuilder = new NavOptions.Builder();
                        NavOptions navOptions = navBuilder.setClearTask(true).build();
                        NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment,null,navOptions);
                    } else {
                        Log.w(TAG, "signInWithCredential:failure", task.getException());

                    }

                }
            });

In my case i needed to remove everything in the back Stack before i open a new fragment so i used this code

navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);

the first line removes the back Stack till it reaches the fragment specified in my case it's the home fragment so it's removes all the back stack completely , and when the user clicks back in the fragment_company he closes the app.

I think your question specifically pertains on how to use the Pop Behavior / Pop To / app:popUpTo (in xml)

In documentation,
Pop up to a given destination before navigating. This pops all non-matching destinations from the back stack until this destination is found.

Example (Simple Job hunting app)
my start_screen_nav graph is like this:

startScreenFragment (start) -> loginFragment -> EmployerMainFragment

                            -> loginFragment -> JobSeekerMainFragment

if I want to navigate to EmployerMainFragment and pop all including startScreenFragment then the code will be:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"
            app:popUpToInclusive="true" />

if I want to navigate to EmployerMainFragment and pop all excluding startScreenFragment then the code will be:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>

if I want to navigate to EmployerMainFragment and pop loginFragment but not startScreenFragment then the code will be:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/loginFragment"
            app:popUpToInclusive="true"/>

OR

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!