Ich lerne, wie man Fragmente benutzt. Ich habe drei Instanzen davon Fragment
, die oben in der Klasse initialisiert werden. Ich füge das Fragment einer Aktivität wie dieser hinzu:
Deklarieren und Initialisieren:
Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();
Ersetzen / Hinzufügen:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
Diese Schnipsel funktionieren ordnungsgemäß. Jedes Fragment ist an die Aktivität angehängt und wird problemlos im Backstack gespeichert.
Also , wenn ich starten A
, C
und dann B
die Stapel sieht wie folgt aus :
| |
|B|
|C|
|A|
___
Und wenn ich den 'Zurück'-Knopf drücke, B
wird zerstört und C
wieder aufgenommen.
Wenn ich das Fragment jedoch A
ein zweites Mal starte, anstatt es vom Backstack fortzusetzen, wird es oben im Backstack hinzugefügt
| |
|A|
|C|
|A|
___
Aber ich möchte A
alle Fragmente darüber (falls vorhanden) wieder aufnehmen und zerstören. Eigentlich gefällt mir nur das Standardverhalten des Backstacks.
Wie schaffe ich das?
Erwartet: ( A
sollte wieder aufgenommen werden und obere Fragmente sollten zerstört werden)
| |
| |
| |
|A|
___
Bearbeiten: (vorgeschlagen von A - C)
Dies ist mein Versuchscode:
private void selectItem(int position) {
Fragment problemSearch = null, problemStatistics = null;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
String backStateName = null;
Fragment fragmentName = null;
boolean fragmentPopped = false;
switch (position) {
case 0:
fragmentName = profile;
break;
case 1:
fragmentName = submissionStatistics;
break;
case 2:
fragmentName = solvedProblemLevel;
break;
case 3:
fragmentName = latestSubmissions;
break;
case 4:
fragmentName = CPExercise;
break;
case 5:
Bundle bundle = new Bundle();
bundle.putInt("problem_no", problemNo);
problemSearch = new ProblemWebView();
problemSearch.setArguments(bundle);
fragmentName = problemSearch;
break;
case 6:
fragmentName = rankList;
break;
case 7:
fragmentName = liveSubmissions;
break;
case 8:
Bundle bundles = new Bundle();
bundles.putInt("problem_no", problemNo);
problemStatistics = new ProblemStatistics();
problemStatistics.setArguments(bundles);
fragmentName = problemStatistics;
default:
break;
}
backStateName = fragmentName.getClass().getName();
fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
ft.replace(R.id.content_frame, fragmentName);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
// I am using drawer layout
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Das Problem ist, wenn ich starte A
und dann B
'Zurück' drücke, B
wird es entfernt und A
fortgesetzt. Wenn Sie ein zweites Mal auf "Zurück" klicken, wird die App beendet. Aber es zeigt ein leeres Fenster und ich muss ein drittes Mal zurück drücken, um es zu schließen.
Auch wenn ich starte A
, dann B
, dann C
, dann B
wieder ...
Erwartet:
| |
| |
|B|
|A|
___
Tatsächlich:
| |
|B|
|B|
|A|
___
Sollte ich onBackPressed()
Anpassungen vornehmen oder fehlt mir etwas?
quelle
OnBackstackChangedListener
damit Sie garantieren können, dass Sie mit dem richtigen Fragment arbeiten.OnBackstackChangedListener
.instanceof
:)A-B-C-B
und einmal zurück drücken, kehren Sie zurück zuA
und nicht zurück zuC
. Das liegt daran, dasspopBackStackImmediate
nicht nur das angegebene Tag, sondern auch alles darüber angezeigt wird. Gibt es dort irgendwelche Arbeiten?Ich denke, diese Methode kann Ihr Problem lösen:
welches ursprünglich in dieser Frage gepostet wurde
quelle
Schritt 1: Implementieren Sie eine Schnittstelle zu Ihrer Aktivitätsklasse
Schritt 2: Wenn Sie ein anderes Fragment aufrufen, fügen Sie diese Methode hinzu:
quelle
quelle
quelle
Eine einfachere Lösung wird diese Linie ändern
ft.replace(R.id.content_frame, A);
zuft.add(R.id.content_frame, A);
Und bitte verwenden Sie in Ihrem XML-Layout
Clickable
bedeutet, dass es von einem Zeigergerät angeklickt oder von einem Touch-Gerät getippt werden kann.Focusable
bedeutet, dass es den Fokus von einem Eingabegerät wie einer Tastatur erhalten kann. Eingabegeräte wie Tastaturen können anhand der Eingaben selbst nicht entscheiden, an welche Ansicht ihre Eingabeereignisse gesendet werden sollen. Sie senden sie daher an die Ansicht mit Fokus.quelle