Używam biblioteki Android Compatibility do implementowania fragmentów i rozszerzyłem przykładowy układ, tak aby fragment zawierał przycisk, który odpala inny fragment.
W okienku wyboru po lewej stronie mam 5 elementów do wyboru - A B C D E
.
Każdy ładuje fragment (przez FragmentTransaction:replace
) w okienku szczegółów -a b c d e
Teraz rozszerzyłem fragment, e
aby zawierał przycisk, który ładuje kolejny fragment e1
również w okienku szczegółów. Zrobiłem to na e
metodzie onClick fragmentu w następujący sposób:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.details_frag, newFrag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
Jeśli dokonam następujących wyborów:
E - e - e1 - D - E
Następnie fragment e
znajduje się w okienku szczegółów. To jest w porządku i czego chcę. Jeśli jednak back
w tym momencie wcisnę przycisk, to nic nie robi. Muszę kliknąć dwukrotnie, ponieważ e1
wciąż jest na stosie. Ponadto po kliknięciu w onCreateView pojawił się wyjątek wskaźnika zerowego:
Aby `` rozwiązać '' ten problem, dodałem następujące po A B C D E
wybraniu:
FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
Zastanawiam się tylko, czy to jest właściwe rozwiązanie, czy też powinienem robić coś innego?
Innym czystym rozwiązaniem, jeśli nie chcesz usuwać wszystkich wpisów stosu ...
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); getSupportFragmentManager().beginTransaction().replace(R.id.home_activity_container, fragmentInstance).addToBackStack(null).commit();
Spowoduje to najpierw wyczyszczenie stosu, a następnie załadowanie nowego fragmentu, więc w dowolnym momencie będziesz mieć tylko jeden fragment w stosie
źródło
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
przed replace (), ponieważ są załadowaniu powołanie FragmentonCreateView()
,onActivityCreated()
itp Przywracanie i destroing fragment od razu jest zły. Fragment może na przykład zarejestrować odbiornik. Wpływa to na wydajność.FragmentTransaction
? Czy jest tylko zła wydajność złego stosu fragmentów?Dzięki odpowiedzi Joachima używam kodu, aby w końcu wyczyścić wszystkie wpisy na stosie.
// In your FragmentActivity use getSupprotFragmentManager() to get the FragmentManager. // Clear all back stack. int backStackCount = getSupportFragmentManager().getBackStackEntryCount(); for (int i = 0; i < backStackCount; i++) { // Get the back stack fragment id. int backStackId = getSupportFragmentManager().getBackStackEntryAt(i).getId(); getSupportFragmentManager().popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE); } /* end of for */
źródło
popBackStack(backStackId, INCLUSIVE)
wrzuci wszystkie fragmenty (stany) z powrotem do backStackId, więc kiedy zdejmiesz najniższyi
, który zamierzasz, wszystkie wyższe powinny zostać usunięte w tym samym czasie. Więc jaki jest sens pętli?Dużo badałem, aby wyczyścić Backstack i wreszcie zobaczyłem Transaction BackStack i zarządzanie nim . Oto rozwiązanie, które najlepiej mi się sprawdziło.
// CLEAR BACK STACK. private void clearBackStack() { final FragmentManager fragmentManager = getSupportFragmentManager(); while (fragmentManager.getBackStackEntryCount() != 0) { fragmentManager.popBackStackImmediate(); } }
Powyższa metoda zapętla wszystkie transakcje w backstacku i usuwa je natychmiast po jednej na raz.
Uwaga: powyższy kod czasami nie działa i napotykam błąd ANR z powodu tego kodu, więc nie próbuj tego.
Zaktualizuj poniższą metodę, aby usunąć wszystkie zwolnienia tej „nazwy” z backstacka.
FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.popBackStack("name",FragmentManager.POP_BACK_STACK_INCLUSIVE);
źródło
Używam podobnego kodu jak te, które używają pętli while, ale wywołuję liczbę wejść w każdej pętli ... więc przypuszczam, że jest nieco wolniejszy
FragmentManager manager = getFragmentManager(); while (manager.getBackStackEntryCount() > 0){ manager.popBackStackImmediate(); }
źródło
Jak napisano w Jak zdjąć fragment z backstacka i LarsH tutaj, możemy przeskoczyć kilka fragmentów od góry do dołu do konkretnego tagu ( razem z tagowanym fragmentem ) przy użyciu tej metody:
fragmentManager?.popBackStack ("frag", FragmentManager.POP_BACK_STACK_INCLUSIVE);
Zastąp „frag” tagiem swojego fragmentu. Pamiętaj, że najpierw powinniśmy dodać fragment do backstacka za pomocą:
fragmentTransaction.addToBackStack("frag")
Jeśli dodamy fragmenty za pomocą
addToBackStack(null)
, nie będziemy usuwać fragmentów w ten sposób.źródło
// pop back stack all the way final FragmentManager fm = getSherlockActivity().getSupportFragmentManager(); int entryCount = fm.getBackStackEntryCount(); while (entryCount-- > 0) { fm.popBackStack(); }
źródło