Ich habe mehrere Fragmente in einer Aktivität. Bei einem Klick auf eine Schaltfläche starte ich ein neues Fragment und füge es dem Backstack hinzu. Ich habe natürlich erwartet, dass die onPause()
Methode des aktuellen Fragments und onResume()
des neuen Fragments aufgerufen wird. Nun, es passiert nicht.
LoginFragment.java
public class LoginFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
final FragmentManager mFragmentmanager = getFragmentManager();
Button btnHome = (Button)view.findViewById(R.id.home_btn);
btnHome.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
HomeFragment fragment = new HomeFragment();
FragmentTransaction ft2 = mFragmentmanager.beginTransaction();
ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
, R.anim.slide_left, R.anim.slide_out_right);
ft2.replace(R.id.middle_fragment, fragment);
ft2.addToBackStack("");
ft2.commit();
}
});
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of LoginFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of loginFragment");
super.onPause();
}
}
HomeFragment.java
public class HomeFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.login_fragment, container, false);
}
@Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
@Override
public void onPause() {
Log.e("DEBUG", "OnPause of HomeFragment");
super.onPause();
}
}
Was ich erwartet hatte, war:
- Wenn der Knopf angeklickt wird, LoginFragment wird mit ersetzt
HomeFragment ,
onPause()
von LoginFragment undonResume()
von HomeFragment wird aufgerufen - Bei der Wiedergabe gedrückt wird, HomeFragment wird poped und LoginFragment gesehen wird , und
onPause()
von HomeFragment undonResume()
von LoginFragment aufgerufen wird.
Was ich bekomme ist,
- Wenn Sie auf die Schaltfläche klicken , ersetzt HomeFragment LoginFragment korrekt . OnResume () von HomeFragment wird aufgerufen, onPause () von LoginFragment wird jedoch nie aufgerufen.
- Wenn Sie zurück drücken, wird HomeFragment korrekt angezeigt , um LoginFragment anzuzeigen . OnPause () von HomeFragment wird aufgerufen, onResume () von LoginFragment wird jedoch nie aufgerufen.
Ist das das normale Verhalten? Warum ist onResume()
das LoginFragment nicht genannt wird , wenn ich die Zurück - Taste drücken.
android
android-fragments
onresume
back-stack
Krishnabhadra
quelle
quelle
Antworten:
Die Fragmente
onResume()
oderonPause()
werden nur aufgerufen, wenn die AktivitätenonResume()
oderonPause()
aufgerufen werden. Sie sind eng mit dem verbundenActivity
.Lesen Sie den Abschnitt Umgang mit dem Fragmentlebenszyklus dieses Artikels .
quelle
onPause()
, nachher gerufen zu werden,onSaveInstanceState()
anstatt davor. Dies kann reproduziert werden, wenn Sie zu einem anderen Kind in meinemFragmentStatePagerAdapter
(sagen Sie, Sie wechseln von Kind 0 zu Kind 2, beachten Sie zu sich selbst, dies geschieht, weil Kind 0 zerstört wird, wenn Kind 2 öffnet )ft2.replace()
, wird dieFragmentTransaction.remove()
Methode aufgerufen und dieLoginfragment
wird entfernt. Beziehen Sie sich darauf . AlsoonStop()
vonLoginFragment
wird statt genanntonPause()
. (Da das neue Fragment das alte vollständig ersetzt).ft2.addtobackstack()
, der Zustand derLoginfragment
wird als ein Bündel gespeichert werden und wenn Sie auf Back - Button ausHomeFragment
,onViewStateRestored()
wird anschließend aufgerufen wirdonStart()
vonLoginFragment
. Also wird irgendwannonResume()
nicht mehr angerufen.quelle
onViewStateRestored
wird angerufen, wenn Sie habensetRetainInstance(true)
Hier ist meine robustere Version von Gors Antwort (die Verwendung von fragment.size () ist unzuverlässig, da die Größe nach dem Aufspringen des Fragments nicht dekrementiert wird.)
Und die Methode 'getCurrentTopFragment':
quelle
Wenn Sie das Fragment wirklich durch ein anderes Fragment ersetzen möchten, sollten Sie verschachtelte Fragmente verwenden .
In Ihrem Code sollten Sie ersetzen
mit
quelle
Seien Sie jedoch vorsichtig, wenn mehr als ein Fragment sichtbar ist
quelle
ViewPager
verweisen Fragmente auf seine Fragmente).Ich habe einen Code, der Ihrem sehr ähnlich ist und ob er auf pause () und onResume () funktioniert. Beim Ändern des Fragments werden diese Funktionen jeweils aktiviert.
Code in Fragment:
Protokoll beim Fragmentwechsel:
Fragment onCreateView:
Aktion beim Zurückpulsieren (in der Aktivität, in der ich das Fragment lade):
quelle
Was ich im Kinderfragment mache:
Und überschreiben Sie dann onResume on ParentFragment
quelle
Sie können einem Fragment einfach kein Fragment hinzufügen. Dies muss in der FragmentActivity geschehen. Ich gehe davon aus, dass Sie das LoginFragment in einer FragmentActivity erstellen. Damit dies funktioniert, müssen Sie das HomeFragment über die FragmentActivity hinzufügen, wenn die Anmeldung geschlossen wird.
Der allgemeine Punkt ist, dass Sie eine FragmentActivity-Klasse benötigen, von der aus Sie jedes Fragment zum FragmentManager hinzufügen. Es ist nicht möglich , diese in einem Fragmente Klasse zu tun.
quelle
Wenn Sie das Fragment in XML hinzufügen, können Sie es nicht dynamisch austauschen. Was passiert, ist, dass sie übermäßig sind, sodass die Ereignisse nicht wie erwartet ausgelöst werden. Das Problem ist in dieser Frage dokumentiert.FragmenManager ersetzen macht Overlay
Verwandeln Sie middle_fragment in ein FrameLayout und laden Sie es wie unten beschrieben. Ihre Ereignisse werden ausgelöst.
quelle
Sie können dies versuchen,
Schritt 1: Überschreiben Sie die Tabselected-Methode in Ihrer Aktivität
Schritt 2: Verwenden Sie die statische Methode, um das zu tun, was Sie in Ihrem Fragment wollen.
quelle
Ich benutze in meiner Tätigkeit - KOTLIN
quelle
Ein Fragment muss immer in eine Aktivität eingebettet sein, und der Lebenszyklus des Fragments wird direkt vom Lebenszyklus der Hostaktivität beeinflusst. Wenn zum Beispiel die Aktivität angehalten wird, sind alle Fragmente darin, und wenn die Aktivität zerstört wird, sind auch alle Fragmente darin
quelle
onPause()
Methode funktioniert in Aktivitätsklasse, die Sie verwenden können:für den gleichen Zweck ..
quelle
Befolgen Sie die folgenden Schritte, und Sie erhalten die erforderliche Antwort
1- Erstellen Sie für beide Fragmente ein neues abstraktes übergeordnetes Fragment.
2- Fügen Sie eine benutzerdefinierte abstrakte Methode hinzu, die von beiden implementiert werden soll.
3- Rufen Sie es von der aktuellen Instanz aus auf, bevor Sie es durch die zweite ersetzen.
quelle
Basierend auf der Antwort von @Gor habe ich ähnlich in Kotlin geschrieben. Platzieren Sie diesen Code in
onCreate()
einer Aktivität. Es funktioniert für ein sichtbares Fragment. Wenn SieViewPager
Fragmente haben, wirdViewPager
das Fragment aufgerufen , kein vorheriges.Nachdem ich https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 gelesen hatte, wurde mir klar, dass es in vielen Situationen besser wäre, neue Fragmente anzuhängen
replace
, nichtadd
. So wirdonResume
in einigen Fällen ein Bedarf verschwinden.quelle
Berufung
ft.replace
sollte onPause (des ersetzten Fragments) und onResume (des ersetzenden Fragments) auslösen.Ich
login_fragment
stelle fest, dass sich Ihr Code auf dem Home-Fragment aufbläst und auch die Ansichten in onCreateView nicht zurückgibt. Wenn dies Tippfehler sind, können Sie zeigen, wie diese Fragmente aus Ihrer Aktivität heraus aufgerufen werden?quelle
Obwohl mit unterschiedlichem Code, hatte ich das gleiche Problem wie das OP, weil ich es ursprünglich verwendet habe
anstatt
Mit "Ersetzen" wird das erste Fragment neu erstellt, wenn Sie vom zweiten Fragment zurückkehren, und daher wird auch onResume () aufgerufen.
quelle
Stellen Sie beim Erstellen einer Fragmenttransaktion sicher, dass Sie den folgenden Code hinzufügen.
Stellen Sie außerdem sicher, dass Sie die Transaktion festschreiben, nachdem Sie sie zum Backstack hinzugefügt haben
quelle