Zastanawiam się, czy to rzeczywiście błąd w Android API:
Mam taką konfigurację:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌-------┐|
| || ||
| || 3 ||
└----┴┴-------┴┘
- To menu, które ładuje fragment # 2 (ekran wyszukiwania) w prawym panelu.
- Jest ekranem wyszukiwania zawierającym fragment nr 3 będący listą wyników.
- Lista wyników jest używana w kilku miejscach (w tym jako funkcjonujący sam w sobie fragment wysokiego poziomu).
Ta funkcja działa doskonale na telefonie (gdzie 1 i 2 i 3 to ActivityFragment
s).
Jednak gdy użyłem tego kodu:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment frag = new FragmentNumber2();
if(toLoad != null) frag.setArguments(toLoad);
transaction.replace(R.id.rightPane, frag);
transaction.commit();
Gdzie R.id.leftPane
i R.id.rightPane
są <fragment>
s w poziomym układzie liniowym.
Rozumiem, że powyższy kod usuwa rezydentny fragment, a następnie zastępuje go nowym fragmentem. Świetnie ... Oczywiście tak się nie dzieje, ponieważ gdy ten kod jest uruchamiany po raz drugi, pojawia się następujący wyjątek:
07-27 15:22:55.940: ERROR/AndroidRuntime(8105): Caused by: java.lang.IllegalArgumentException: Binary XML file line #57: Duplicate id 0x7f080024, tag null, or parent id 0x0 with another fragment for FragmentNumber3
Jest to spowodowane tym, że kontener dla FragmentNumber3 został zduplikowany i nie ma już unikalnego identyfikatora. Początkowy fragment nie został zniszczony (?) Przed dodaniem nowego (moim zdaniem oznacza to, że nie został zastąpiony ).
Czy ktoś może mi powiedzieć, czy jest to możliwe ( ta odpowiedź sugeruje, że tak nie jest), czy to błąd?
Odpowiedzi:
Zagnieżdżone fragmenty nie są obecnie obsługiwane. Próba umieszczenia fragmentu w interfejsie użytkownika innego fragmentu spowoduje niezdefiniowane i prawdopodobnie nieprawidłowe zachowanie.
UWAGA (zgodnie z tym dokumentem ): „ Uwaga: nie można wypełnić układu do fragmentu, gdy układ ten zawiera a
<fragment>
. Zagnieżdżone fragmenty są obsługiwane tylko wtedy, gdy są dodawane do fragmentu dynamicznie ”.źródło
Fragment
są teraz częścią interfejsu API systemu Android, ojej! developer.android.com/about/versions/… .Biblioteka obsługi systemu Android obsługuje teraz również zagnieżdżone fragmenty , dzięki czemu można wdrażać projekty zagnieżdżonych fragmentów w systemie Android 1.6 i nowszych.
Aby zagnieździć fragment, po prostu wywołaj funkcję getChildFragmentManager () na fragmencie, do którego chcesz dodać fragment. Zwraca to FragmentManager, którego można używać tak, jak zwykle w działaniu najwyższego poziomu do tworzenia transakcji fragmentarycznych. Na przykład, oto kod, który dodaje fragment z istniejącej klasy Fragment:
Aby dowiedzieć się więcej o zagnieżdżonych fragmentach, zapoznaj się z samouczkami
Część 1
Część 2
Część 3
a tutaj jest post SO, który omawia najlepsze praktyki dla zagnieżdżonych fragmentów .
źródło
.. możesz wyczyścić zagnieżdżony fragment w
destroyview
metodzie fragmentu nadrzędnego :źródło
Mam aplikację, którą tworzę, która ma podobny układ z zakładkami na pasku akcji, która uruchamia fragmenty, niektóre z tych fragmentów mają w sobie wiele osadzonych fragmentów.
Otrzymałem ten sam błąd, gdy próbowałem uruchomić aplikację. Wygląda na to, że jeśli utworzysz wystąpienie fragmentów w układzie XML po odznaczeniu karty, a następnie ponownym wybraniu, wystąpi błąd inflatora.
Rozwiązałem to, zastępując wszystkie fragmenty w xml Linearlayouts, a następnie używając menedżera fragmentów / transakcji fragmentów do utworzenia instancji fragmentów, wszystko wydaje się działać poprawnie, przynajmniej na poziomie testowym.
Mam nadzieję, że to ci pomoże.
źródło
Zmierzyłem się z tym samym problemem, zmagałem się z nim przez kilka dni i powinienem powiedzieć, że najłatwiejszym sposobem rozwiązania tego problemu jest użycie fragment.hide () / fragment.show (), gdy karta jest zaznaczona / niezaznaczona ().
Gdy nastąpi obrót ekranu, wszystkie fragmenty nadrzędne i podrzędne zostaną poprawnie zniszczone.
Takie podejście ma również jedną dodatkową zaletę - użycie funkcji hide () / show () nie powoduje utraty stanu widoków fragmentów, więc nie ma potrzeby przywracania poprzedniej pozycji przewijania na przykład dla ScrollViews.
Problem w tym, że nie wiem, czy dobrze jest nie odrywać fragmentów, gdy nie są one widoczne. Myślę, że oficjalny przykład TabListener został zaprojektowany z myślą o tym, że fragmenty są wielokrotnego użytku i nie powinieneś zanieczyszczać ich pamięcią, jednak myślę, że jeśli masz tylko kilka zakładek i wiesz, że użytkownicy będą często się między nimi przełączać będzie właściwe, aby zachować ich przywiązanie do bieżącej działalności.
Chciałbym usłyszeć komentarze od bardziej doświadczonych programistów.
źródło
Jeśli okaże się, że zagnieżdżony fragment nie jest usuwany lub kopiowany (np. Po ponownym uruchomieniu działania, przy obrocie ekranu), spróbuj zmienić:
do
Jeśli powyższe nie pomoże, spróbuj:
Nauczyłem się tutaj
źródło