W FragA
Androidzie fragment (powiedzmy ) zostanie dodany do stosu, a inny fragment (powiedzmy FragB
) znajdzie się na górze. Teraz po uderzeniu wraca FragA
na górę i onCreateView()
zostaje wywołany. Teraz byłem FragA
w szczególnym stanie, zanim FragB
zostałem zepchnięty na to.
Moje pytanie brzmi: jak mogę przywrócić FragA
poprzedni stan? Czy istnieje sposób na zapisanie stanu (na przykład w pakiecie), a jeśli tak, to którą metodę należy zastąpić?
android
android-fragments
pankajagarwal
źródło
źródło
onSaveInstanceState
jest wywoływana tylko wtedy, gdy odpowiadające jej działanie jest również zamykane.Fragment
onSaveInstanceState(Bundle outState)
nigdy nie zostanie wywołany, chyba że aktywność fragmentu wezwie go na siebie i dołączone fragmenty. Dlatego ta metoda nie zostanie wywołana, dopóki coś (zazwyczaj rotacja) nie wymusi działaniaSaveInstanceState
i nie przywróci jej później. Ale jeśli masz tylko jedno działanie i duży zestaw fragmentów w nim (przy intensywnym użyciureplace
) i aplikacja działa tylko w jednej orientacji, działanieonSaveInstanceState(Bundle outState)
może nie być wywoływane przez długi czas.Znam trzy możliwe obejścia.
Pierwszy:
użyj argumentów fragmentu do przechowywania ważnych danych:
Drugi, ale mniej pedantyczny sposób - trzymaj zmienne w singletonach
Trzeci - nie
replace()
fragmentuje, ale zamiast tegoadd()
/show()
/hide()
je.źródło
Fragment.onSaveInstanceState()
nikt nie dzwonił. Po prostu zapisz własne dane do argumentu, w tym elementy w widoku listy lub tylko ich identyfikatory (jeśli masz inny scentralizowany menedżer danych). Nie ma potrzeby zapisywania pozycji widoku listy - to zostało zapisane i przywrócone automatycznie.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
jest zawszenull
. Jaki jest problem?getArguments()
jest ZDECYDOWO właściwą drogą, w tym zagnieżdżonymi fragmentami w ViewPager. Używam 1 działania i zamieniam wiele fragmentów we / wy, a to działa idealnie. Oto prosty test pozwalający zweryfikować proponowane rozwiązanie: 1) przejdź od fragmentu A do fragmentu B; 2) dwukrotnie zmień orientację urządzenia; 3) naciśnij przycisk powrotu na urządzeniu.setArguments(new Bundle());
nadpisał stary Bundle. Dlatego upewnij się, że utworzyłeś fragment tylko raz, a następnie użyj tej instancji zamiast tworzenia za każdym razem nowego.Zwróć uwagę, że jeśli pracujesz z fragmentami za pomocą ViewPagera, jest to całkiem łatwe. Wystarczy tylko zadzwonić do tej metody:
setOffscreenPageLimit()
.Zgodnie z dokumentacją:
Podobny problem tutaj
źródło
Po prostu raz nadmuchaj swój widok.
Przykład:
}
źródło
Fragment
odnosi się do jego głównego widoku, nie zrobi tego. Podczas gdy odwołanie przez niektóre elementy GC-root , podobnie jak globalna właściwość statyczna, będzie zmienną wątku inną niż ui.Fragment
Przykład nie GC głównego, dzięki czemu mogą być zbierane śmieci. Tak samo będzie z jego głównym poglądem.Pracowałem z bardzo podobnym problemem. Ponieważ wiedziałem, że będę często wracał do poprzedniego fragmentu, sprawdziłem, czy fragment
.isAdded()
jest prawdziwy, a jeśli tak, to zamiasttransaction.replace()
robić atransaction.show()
. Dzięki temu fragment nie zostanie odtworzony, jeśli jest już na stosie - nie jest potrzebne zapisywanie stanu.Inną rzeczą, o której należy pamiętać, jest to, że chociaż zachowuje to naturalny porządek dla samych fragmentów, nadal możesz potrzebować obsługiwać samą aktywność, która jest niszczona i odtwarzana po zmianie orientacji (konfiguracji). Aby obejść ten problem w AndroidManifest.xml dla swojego węzła:
W Androidzie 3.0 i nowszych
screenSize
jest to najwyraźniej wymagane.Powodzenia
źródło
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
w swoim manifeście. Zamiast tego dowiedz się, jak zapisywać i przywracać stan, na przykład stąd: speakerdeck.com/cyrilmottier/…Najlepsze rozwiązanie, które znalazłem, znajduje się poniżej:
onSavedInstanceState (): zawsze wywoływana wewnątrz fragmentu, gdy aktywność ma zostać zamknięta (Przenieś aktywność z jednej do drugiej lub zmiany konfiguracji). Więc jeśli wywołujemy wiele fragmentów tej samej aktywności, musimy zastosować następujące podejście:
Użyj OnDestroyView () fragmentu i zapisz cały obiekt wewnątrz tej metody. Następnie OnActivityCreated (): sprawdź, czy obiekt ma wartość null, czy nie (ponieważ ta metoda wywołuje za każdym razem). Teraz przywróć stan obiektu tutaj.
Zawsze działa!
źródło
jeśli obsługujesz zmiany konfiguracji w aktywności fragmentu określonej w manifeście Androida w ten sposób
wtedy
onSaveInstanceState
fragment nie zostanie wywołany, asavedInstanceState
obiekt zawsze będzie pusty.źródło
nie uważam, że
onSaveInstanceState
to dobre rozwiązanie. po prostu używa do działalności, która została zniszczona.Od Androida 3.0 Fragmenem zarządza FragmentManager, warunek jest następujący: jedna czynność mapująca wiele fragmentów, gdy fragment zostanie dodany (nie zastąpi: zostanie odtworzony) w backStack, widok zostanie zniszczony. gdy wrócisz do ostatniego, wyświetli się jak poprzednio.
Myślę więc, że fragmentManger i transakcja są wystarczająco dobre, aby sobie z tym poradzić.
źródło
Użyłem podejścia hybrydowego do fragmentów zawierających widok listy. Wydaje się, że działa wydajnie, ponieważ nie zastępuję obecnego fragmentu, a raczej dodaję nowy fragment i ukrywam obecny. W działaniu, w którym znajdują się moje fragmenty, mam następującą metodę:
Używam tej metody w moim fragmencie (zawierającym widok listy) za każdym razem, gdy element listy jest klikany / stuknięty (i dlatego muszę uruchomić / wyświetlić fragment szczegółów):
getFragmentTags()
zwraca tablicę ciągów, których używam jako znaczników dla różnych fragmentów, kiedy dodam nowy fragment (patrztransaction.add
metoda waddFragment
metodzie powyżej).We fragmencie zawierającym widok listy robię to w jego metodzie onPause ():
Następnie w onCreateView fragmentu (właściwie w metodzie, która jest wywoływana w onCreateView) przywracam stan:
źródło
W końcu po wypróbowaniu wielu z tych skomplikowanych rozwiązań, ponieważ potrzebowałem tylko zapisać / przywrócić pojedynczą wartość w moim fragmencie (zawartość EditText) i chociaż może to nie być najbardziej eleganckie rozwiązanie, utworzenie SharedPreference i przechowywanie mojego stanu tam pracował dla mnie
źródło
Prosty sposób na przechowywanie wartości pól w różnych fragmentach w działaniu
Utwórz instancje fragmentów i dodaj zamiast zamieniać i usuwać
Następnie po prostu pokaż i ukryj fragmenty, zamiast dodawać je i usuwać ponownie
;
źródło
źródło