How to clear navigation Stack after navigating to

2019-01-25 06:58发布

问题:

I am using The new Navigation Architecture Component in android and I am stuck in clearing the navigation stack after moving to a new fragment.

Example: I am in the loginFragment and I want this fragment to be cleared from the stack when I navigate to the home fragment so that the user will not be returned back to the loginFragment when he presses the back button.

I am using a simple NavHostFragment.findNavController(Fragment).navigate(R.id.homeFragment) to navigate.

Current Code :

mAuth.signInWithCredential(credential)
            .addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment);
                    } else {
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                    }
                }
            });

I tried using the NavOptions in the navigate(), but the back button is still sending me back to the loginFragment

NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setPopUpTo(R.id.homeFragment, false).build();   
             NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment, null, navOptions);

回答1:

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())

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).



回答2:

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"


回答3:

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());

                    }

                }
            });