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);
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.
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.
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"
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());
}
}
});
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.
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"/>
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()
}
}