Ich baue gerade eine Anwendung für Android (14 <= SDK <= 21), indem ich eine ActionBarActivity
und mehrere Fragments
wie ListFragment
und MapFragment
verwende, die innerhalb einer einzelnen FrameLayout
-Ansicht ausgetauscht werden.
Die ActionBarActivity ersetzt das Fragment A automatisch/schreibt es aus. Wenn der Benutzer auf eine Schaltfläche tippt, wird die Hosting-Aktivität ein neues anderes Fragment B ersetzt/festgelegt. Mein Ziel ist es, den Benutzer auf das Fragment A zurückzusetzen, sobald er die Zurück-Taste drückt .
Ein bisschen Code jetzt.
Hauptaktivität
public class MainActivity extends ActionBarActivity implements StopFragment.OnFragmentInteractionListener,
StopItemFragment.OnFragmentInteractionListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
fragmentManager.enableDebugLogging(true);
...
if (fragmentManager.findFragmentById(R.id.content_frame) == null) {
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, list)
.addToBackStack(null)
.commit();
}
...
@Override
public void onFragmentInteraction(String id) {
selectItem(Integer.parseInt(id));
}
private void selectItem(int position) {
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
...
}
}
Problem
Selbst wenn addToBackStack()
aufgerufen wird, kann ich mit Fragment B nicht zu Fragment A zurückkehren. MainActivity ist direkt geschlossen .. Dennoch habe ich versucht, den Back-Stack ohne Erfolg alleine zu verwalten. Ich kann sehen, dass sich das Fragment auf dem Stapel befindet, aber wenn ich popBackStackImmediate()
aufrufe, wird Fragment A herausgefahren und die Fragmenttransaktion wird nicht ausgeführt. (Erstes Rückdrücken nichts passiert, zweite Aktivität geschlossen)
Ich füge auch das FragmentManager-Logcat bei:
http://Pastebin.com/hFLHprL8
Für diejenigen, die noch nach einer Lösung suchen.
In der Activity
-Hauptklasse (die die Fragmente hostet) überschreiben Sie einfach onBackPressed()
.
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Es gibt keine onBackPressed()
-Methode in fragment, und diese Methode gilt nur für die activity
. Wenn Sie also die Zurück-Taste drücken, wird das Standardverhalten von activity
angezeigt
sie gelangen entweder zur vorherigen Aktivität (falls vorhanden) oder zur App wird verlassen.
Jetzt müssen wir diese Methode außer Kraft setzen, um der Variable activity
mitzuteilen, dass beim Drücken der Zurück-Taste, wenn sich im Back-Stack Fragmente befinden, diese herausgefahren werden (und dies ist, wenn die addToBackStack()
im Bild erscheint). Ansonsten folgen Sie dem Standardverhalten.
Versuchen Sie dies (Anmerkung add not replace für fragmentA und addToBackStack () für fragmentB)
StopItemFragment list = StopItemFragment.newInstance(null); //A - extends ListFragment
fragmentManager.beginTransaction()
.add(R.id.content_frame, list)
.commit();
und
StopFragment fragment = StopFragment.newInstance(null, null); //B - extends Fragment
...
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("FragmentB")
.commit();
Ich musste beginTransaction()
und commit()
von FragmentManager
manuell aufrufen.
Gelöst durch Überschreiben von onBackPressed()
:
@Override
public void onBackPressed() {
...
if (fragmentManager.getBackStackEntryCount() > 1){
fragmentManager.popBackStackImmediate();
fragmentManager.beginTransaction().commit();
} else {
//handle finish
finish(); // Closes app
}
}
Wenn Sie mit addToBackStack () & popBackStack () kämpfen, verwenden Sie einfach
FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`
Finden Sie in Ihrer Aktivität In OnBackPressed () heraus, was Sie von Tag zu Tag finden und erledigen Sie dann Ihre Sachen
Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
if (home instanceof HomeFragment && home.isVisible()) {
// do you stuff
}
Weitere Informationen https://github.com/DattaHujare/NavigationDrawer Ich verwende niemals addToBackStack () zur Behandlung von Fragmenten.
der Grund, warum popBackStack()
und popBackStackImmediatly()
auf die Tatsache zurückzuführen sind, dass Sie dieses Fragment (das Sie platzieren möchten) nicht zum backStack hinzugefügt haben. Dazu müssen Sie zum Zeitpunkt der Transaktion addToBackStack () aufrufen, um Ihr Fragment hinzuzufügen oder zu ersetzen.