2013-09-05 15 views
11

Właściwie zawsze użyć ponownie mój pogląd w moich fragmentów tak:Fragment - czy powinienem ponownie wykorzystać widok w onCreateView i jak mam to zrobić?

private View mView = null; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    if (mView == null) 
     mView = inflater.inflate(R.layout.view); 
    return mView; 
} 

To działało, z viewpager i tak dalej. Teraz zacząłem używać moje fragmenty w prostych czynności, jak również i wtedy i tylko wtedy, dodaję fragment do backstack, to nie z powodu java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

Więc moje pytania to:

  • Czy to jest ok , jeśli sprawdzę, czy widoki są nadrzędne, usuń je i dodaj do nowego rodzica?
  • Czy powinienem zawsze odtwarzać widok i nigdy go nie używać? Jeśli tak, dlaczego?
  • Czy istnieją inne punkty, w których ponowne wykorzystanie widoku zakończy się niepowodzeniem?

Odpowiedz

11

Może to może pomóc w zrozumieniu zachowania. Jeśli sprawdzeniu FragmentManagerImpl.java znajdziesz następujące:

Najpierw musimy utworzyć widok wywołując onCreateView() (linii 845), a następnie zawijany utworzony widok z innego widoku, który staje się dominująca naszego widzenia (linii 848 -849). Oznacza to, że nasz widok nie staje się dzieckiem prawdziwego kontenera, ale teraz jest dzieckiem widoku opakowania. Problem z ponownym użyciem występuje, gdy widok zostanie usunięty z pojemnika (wiersz 998). FragmentManager usuwa widok opakowania z kontenera, ale widok rzeczywisty pozostaje dodany do widoku opakowania nadrzędnego. To właśnie powoduje występujący problem.

W ten sposób, jeśli usuniesz widok z jego rodzica, może on działać. Nawet wiedząc to, nie polecałbym ponownego wykorzystania widoków w tym fragmencie, ponieważ widoki mogą żyć nieco dłużej niż fragmenty, ponieważ mogą być używane w "znikających" animacjach nawet po zniszczeniu fragmentu. Jeśli spróbujesz usunąć taki widok z rodzica w tym czasie, animacja może zostać zerwana.

Innym argumentem za brakiem buforowania widoku jest to, że system Android nie obsługuje przeglądania widoku fragmentami według projektu. Zapamiętaj ListAdapter pozwalając na ponowne wykorzystanie widoków? Android dba o buforowanie i właściwe ponowne wykorzystanie tych widoków. Nie dotyczy to jednak fragmentów.

+0

Dzięki za wyjaśnienie, które sprawia, że ​​jest dla mnie bardziej zrozumiały – prom85

6

Jestem obecnie ponowne pogląd o coś takiego:

if(view == null){ 
    view = (ViewGroup) inflater.inflate(R.layout.news_list, container, false); 
} else { 
    ((ViewGroup) view.getParent()).removeView(view); 
} 
return view; 

ja nie wiem, czy w ten sposób jest poprawny, ale wydaje się działać dla mnie ..

uwaga: "Używam tego podejścia, ponieważ mam widok listy w fragmencie, a kiedy użytkownik kliknie na element, ładuje nowy fragment (menedżer fragmentów zastępuje obecny fragment listy). Następnie, gdy użytkownik uderzy w backbutton, ponieważ ponownie korzystam z tego samego starego widoku fragmentu (który nie jest niszczony po usunięciu z FM), użytkownik kontynuuje przeglądanie listy w pozycji, w jakiej znajdował się przed otwarciem fragmentu fragmentu.

+0

Hi @edrain Twoje rozwiązanie działa dobrze, ale nie usuwa widoku z kontenera, nawet gdy wybrałem fragment. –

Powiązane problemy