wake-up-neo.com

So löschen Sie den Navigationsstapel nach dem Navigieren zu einem anderen Fragment in Android

Ich verwende die neue Navigationsarchitektur-Komponente in Android und bin beim Löschen festgefahren der Navigationsstapel nach dem Verschieben auf ein neues Fragment.

Beispiel: Ich bin in loginFragment und möchte, dass dieses Fragment vom Stapel gelöscht wird, wenn ich zum Ausgangsfragment navigiere, damit der Benutzer nicht zum loginFragment zurückkehrt, wenn er die Zurück-Taste drückt.

Ich benutze ein einfaches NavHostFragment.findNavController (Fragment) .navigate (R.id.homeFragment) , um zu navigieren.

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

Ich habe versucht, NavOptions in navigate () zu verwenden, aber der Zurück-Button schickt mich immer noch zurück zum Login-Fragment

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);
50
Youssef El Behi

Fügen Sie dem Action-Tag zunächst die Attribute app:popUpTo='your_nav_graph_id' Und app:popUpToInclusive="true" Hinzu.

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

Als zweites navigieren Sie zum Ziel, wobei Sie die obige Aktion als Parameter verwenden.

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

Weitere Informationen finden Sie in docs .

[~ # ~] note [~ # ~] : Wenn Sie mit der Methode navigate(@IdRes int resId) navigieren, erhalten Sie nicht die gewünschte Ergebnis. Daher habe ich die Methode navigate(@NonNull NavDirections directions) verwendet.

73
Subhojit Shaw

HINWEIS: Klare Aufgabe ist veraltet, offizielle Beschreibung ist

Diese Methode ist veraltet. Verwenden Sie setPopUpTo (int, boolean) mit der ID des NavController-Diagramms und setzen Sie inclusive auf true.

Alte Antwort

Wenn Sie den ganzen Code nicht durchgehen möchten, können Sie einfach Clear Task im Launch Options in den Eigenschaften der Aktion.

Launch Options

Bearbeiten: Ab Android= Studio 3.2 Beta 5 ist die Option "Aufgabe löschen" im Fenster "Startoptionen" nicht mehr sichtbar, Sie jedoch Sie können es weiterhin im XML-Code der Navigation im action -Tag verwenden, indem Sie es hinzufügen

app:clearTask="true"
11
Mel

Ich habe es endlich herausgefunden, dank Wie kann ich UP in der Navigation für ein Fragment mit der neuen Navigationsarchitektur-Komponente deaktivieren?

Ich musste .setClearTask (true) als NavOption angeben.

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

                    }

                }
            });
4
Youssef El Behi

In meinem Fall musste ich alles im hinteren Stapel entfernen, bevor ich ein neues Fragment öffne, also habe ich diesen Code verwendet

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

die erste Zeile entfernt den Backstack, bis das in meinem Fall angegebene Fragment erreicht ist. Es ist das Home-Fragment, sodass der gesamte Backstack vollständig entfernt wird. Wenn der Benutzer in der fragment_company zurückklickt, schließt er die App.

3
Nour Ahmed

Ich denke, Ihre Frage bezieht sich speziell auf die Verwendung des Pop-Verhaltens/Pop To/App: popUpTo (in xml)

In der Dokumentation
Pop-up zu einem bestimmten Ziel, bevor Sie navigieren. Dadurch werden alle nicht übereinstimmenden Ziele vom Backstack abgerufen, bis dieses Ziel gefunden wurde.

Beispiel (Einfache Jobsuche-App)
meine start_screen_nav Grafik ist wie folgt:

startScreenFragment (start) -> loginFragment -> EmployerMainFragment

                            -> loginFragment -> JobSeekerMainFragment

wenn ich zu EmployerMainFragment navigieren und all pop einschließlich startScreenFragment dann lautet der Code:

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

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

wenn ich zu EmployerMainFragment navigieren und all pop ohne startScreenFragment dann lautet der Code:

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

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

wenn ich zu EmployerMainFragment und pop loginFragment navigieren will aber nicht startScreenFragment dann lautet der Code:

        <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"/>
1
dongkichan

Sie können das Zurückdrücken der Basisaktivität wie folgt überschreiben:

override fun onBackPressed() {

  val navigationController = nav_Host_fragment.findNavController()
  if (navigationController.currentDestination?.id == R.id.firstFragment) {
    finish()
  } else if (navigationController.currentDestination?.id == R.id.secondFragment) {
    // do nothing
  } else {
    super.onBackPressed()
  }

}
0
ROHIT LIEN