Mam wiele fragmentów wewnątrz działania. Po kliknięciu przycisku zaczynam nowy fragment, dodając go do backstacka. Naturalnie spodziewałem się, że zostanie wywołana onPause()
metoda obecnego Fragmentu i onResume()
nowego Fragmentu. Cóż, to się nie dzieje.
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();
}
}
Spodziewałem się
- Po kliknięciu przycisku LoginFragment zostaje zastąpiony
HomeFragment ,
onPause()
z LoginFragment , aonResume()
od HomeFragment jest wywoływana - Po powrocie powoduje HomeFragment jest poped się i LoginFragment widać, a
onPause()
od HomeFragment ionResume()
od LoginFragment zostanie wywołany.
Dostaję to
- Po kliknięciu przycisku HomeFragment poprawnie zastępuje LoginFragment , wywoływana jest funkcja onResume () funkcji HomeFragment , ale funkcja onPause () funkcji LoginFragment nigdy nie jest wywoływana.
- Po ponownym naciśnięciu HomeFragment wyświetla się poprawnie, aby pokazać LoginFragment , onPause () z HomeFragment zostaje wywołany, ale onResume () z LoginFragment nigdy nie zostaje wywołany.
Czy to jest normalne zachowanie? Dlaczego onResume()
od LoginFragment nie uzyskiwanie nazywa się po naciśnięciu przycisku Wstecz.
android
android-fragments
onresume
back-stack
Krysznabhadra
źródło
źródło
Odpowiedzi:
Fragmenty
onResume()
lubonPause()
będą wywoływane tylko wtedy, gdy zostaną wywołane DziałaniaonResume()
lubonPause()
. Są ściśle powiązane zActivity
.Przeczytaj sekcję Obsługa cyklu życia fragmentu tego artykułu .
źródło
onPause()
wywołaniemonSaveInstanceState()
zamiast przed nim. To może być powielana jeśli was do innego dziecka w moimFragmentStatePagerAdapter
(mówią, że przejście od dziecka do dziecka 2: 0, notatki do siebie, tak się dzieje, ponieważ dziecko 0 jest zniszczona, gdy dziecko 2 otwiera )ft2.replace()
,FragmentTransaction.remove()
wywoływana jest metoda, aLoginfragment
zostanie usunięty. Zobacz to . WięconStop()
odLoginFragment
będziemy nazywać zamiastonPause()
. (Ponieważ nowy fragment całkowicie zastępuje stary).ft2.addtobackstack()
, stanuLoginfragment
zostanie zapisany jako pakiet i po kliknięciu przycisku z tyłuHomeFragment
,onViewStateRestored()
będzie zwany następnieonStart()
odLoginFragment
. Więc w końcuonResume()
nie zostanie nazwany.źródło
onViewStateRestored
nazywa się, jeśli maszsetRetainInstance(true)
Oto moja bardziej niezawodna wersja odpowiedzi Gor (użycie fragments.size () jest niewiarygodne, ponieważ rozmiar nie jest zmniejszany po wysunięciu fragmentu)
I metoda „getCurrentTopFragment”:
źródło
Jeśli naprawdę chcesz zastąpić fragment w innym fragmencie, powinieneś użyć zagnieżdżonych fragmentów .
W swoim kodzie powinieneś zastąpić
z
źródło
ale bądź ostrożny, jeśli widoczny jest więcej niż jeden fragment
źródło
ViewPager
przy fragmentach będzie się odnosił do jego fragmentów).Mam kod bardzo podobny do twojego i jeśli działa onPause () i onResume (). Podczas zmiany fragmentu funkcje te są odpowiednio aktywowane.
Kod we fragmencie:
Zaloguj się, gdy zmiana fragmentu:
Fragment onCreateView:
Akcja po odesłaniu pulsu (w działaniu, w którym ładuję fragment):
źródło
Co robię we fragmencie podrzędnym:
A następnie zastąp overResume na ParentFragment
źródło
Po prostu nie można dodać fragmentu do fragmentu. To musi się zdarzyć w FragmentActivity. Zakładam, że tworzysz LoginFragment w FragmentActivity, więc aby to zadziałało, musisz dodać HomeFragment poprzez FragmentActivity, gdy logowanie zostanie zamknięte.
Ogólnie rzecz biorąc, potrzebujesz klasy FragmentActivity, z której dodajesz każdy fragment do menedżera FragmentManager. Nie można tego zrobić wewnątrz klasy Fragment.
źródło
Jeśli dodasz fragment w XML, nie będziesz mógł zamieniać go dynamicznie. To, co się dzieje, to przesada, więc wydarzenia nie strzelają tak, jak można by się spodziewać. Problem został udokumentowany w tym pytaniu. FragmenManager replace tworzy nakładkę
Przekształć middle_fragment w FrameLayout i załaduj go jak poniżej, a twoje wydarzenia się uruchomią.
źródło
Możesz spróbować
Krok 1: Zastąp metodę Tabselected w swojej aktywności
Krok 2: Używając metody statycznej, rób co chcesz w swoim fragmencie,
źródło
Używam w swojej działalności - KOTLIN
źródło
Fragment musi zawsze być osadzony w działaniu, a na cykl życia fragmentu ma bezpośredni wpływ cykl życia hosta. Na przykład, gdy aktywność jest wstrzymana, podobnie jak wszystkie jej fragmenty, a gdy aktywność jest zniszczona, podobnie jak wszystkie fragmenty
źródło
onPause()
metoda działa w klasie aktywności, której możesz użyć:w tym samym celu ..
źródło
Wykonaj poniższe kroki, a otrzymasz potrzebną odpowiedź
1- Dla obu fragmentów utwórz nowy abstrakcyjny nadrzędny.
2- Dodaj niestandardową metodę abstrakcyjną, która powinna być zaimplementowana przez obie z nich.
3- Wywołaj go z bieżącej instancji przed zastąpieniem drugą.
źródło
Na podstawie odpowiedzi @Gor napisałem podobnie w Kotlinie. Umieść ten kod w
onCreate()
działaniu. Działa dla jednego widocznego fragmentu. Jeśli maszViewPager
fragmenty, wywołaViewPager
fragment, a nie poprzedni.Po przeczytaniu https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 Zrozumiałem, że w wielu sytuacjach lepiej byłoby dołączyć nowe fragmenty
replace
, nieadd
. DlategoonResume
w niektórych przypadkach potrzeba zniknie.źródło
Wywołanie
ft.replace
powinno wyzwalać onPause (zastępowanego fragmentu) i onResume (zastępującego fragmentu).Zauważyłem, że twój kod zawyża
login_fragment
fragment domowy, a także nie zwraca widoków w onCreateView. Jeśli są to literówki, czy możesz pokazać, jak te fragmenty są wywoływane z Twojej aktywności?źródło
Chociaż z innym kodem, doświadczyłem tego samego problemu co OP, ponieważ pierwotnie użyłem
zamiast
Przy „replace” pierwszy fragment jest odtwarzany po powrocie z drugiego fragmentu, dlatego też wywoływana jest również funkcja onResume ().
źródło
Podczas tworzenia transakcji fragmentu pamiętaj o dodaniu następującego kodu.
Upewnij się także, aby zatwierdzić transakcję po dodaniu jej do backstacka
źródło