Różnica między onCreateView i onViewCreated we fragmencie


119

Jaka jest zasadnicza różnica między tymi dwiema metodami? Kiedy tworzę TextView, czy powinienem używać jednego nad drugim w celu zwiększenia wydajności?

Edycja: jaka jest różnica między

onCreateView() {
  root = some view
  View v = new View(some context);
  root.add(v);
  return root;
}


onViewCreated() {
  View v = new View(some context);
  getView().add(v);
}

Dodałem edycję, aby wyjaśnić moje zamieszanie. Jeśli jedna metoda następuje zaraz po drugiej, dlaczego są dwie? Czy nie można stworzyć całego widoku za pomocą jednej metody, jak powyżej?
Smith

7
Jeśli musisz wygooglować i zgadywać, prawdopodobnie istnieją źle nazwane metody.
Balázs Németh,

Odpowiedzi:


85

Mamy do czynienia z awariami podczas inicjowania widoku w programie onCreateView.

Powinieneś nadmuchać swój układ, onCreateViewale nie powinieneś inicjować innych widoków za pomocą findViewByIdw onCreateView.

Ponieważ czasami widok nie jest poprawnie zainicjowany. Dlatego zawsze używaj findViewByIdin onViewCreated(gdy widok jest w pełni utworzony), a także przekazuje widok jako parametr.

onViewCreated to upewnienie się, że widok jest w pełni stworzony.

onViewCreated Android Documentation

Wywoływana natychmiast po zwróceniu onCreateView( android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle), ale przed przywróceniem do widoku jakiegokolwiek zapisanego stanu. Daje to podklasom szansę na zainicjowanie się, gdy dowiedzą się, że ich hierarchia widoków została całkowicie utworzona. Hierarchia widoków fragmentu nie jest jednak w tym momencie dołączona do jego rodzica.


4
Dzięki. Ja też stanąłem przed tym problemem i użyłem komponentu. post(...), aby poczekać, aż zostanie wyświetlona. Prawdopodobnie spowoduje, że findViewById i inna inicjalizacja w onViewCreated.
CoolMind

22
Skąd cytowano ten tekst? Nie mogłem znaleźć tego w oficjalnej dokumentacji.
Daniel

Czy możesz zamieścić odniesienie do cytowanego tutaj oświadczenia z witryny programistów?
Namrata Bagerwal

4
To nie jest poprawne. Możesz znaleźć widok w onCreateView, ale dopiero po jego zawyżeniu i tylko z widoku, który już został zawyżony. Fragment.findViewById () nie jest bezpieczna, ale View.findViewById () jest bezpieczna, jeśli już napełniłeś widok fragmentu.
colintheshots

46

onViewCreatedjest wywoływana natychmiast po onCreateView(metodzie, którą inicjalizujesz i tworzysz wszystkie obiekty, w tym swoje TextView), więc nie jest to kwestia wydajności.

Ze strony programisty:

onViewCreated (widok widoku, pakiet zapisanyInstanceState)

Wywoływana natychmiast po zwrocie onCreateView (LayoutInflater, ViewGroup, Bundle), ale przed przywróceniem dowolnego zapisanego stanu do widoku. Daje to podklasom szansę na zainicjowanie się, gdy dowiedzą się, że ich hierarchia widoków została całkowicie utworzona. Hierarchia widoków fragmentu nie jest jednak w tym momencie dołączona do jego rodzica.

Źródło: fragment # onViewCreated


28

Lepiej jest przypisać podziały do ​​pól w onViewCreated. Dzieje się tak, ponieważ platforma automatycznie sprawdza wartość null, aby upewnić się, że hierarchia widoków fragmentu została utworzona i zawyżona (jeśli używasz pliku układu XML).

Fragment kodu z: FragmentManger.java

// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);

// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
    f.mView.setSaveFromParentEnabled(false);
    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
}

6
oddziela również logikę inicjalizacji z hierarchii widoku logiki inflacji / tworzenia
orangemako

1
To ciekawe, czy masz dodatkowe zasoby wyjaśniające, dlaczego to podejście jest lepsze? Czy to oznacza, że ​​każda metoda onCreateView powinna składać się tylko z „return inflater.inflate (R.layout.layout_file, container, false)”; a onviewcreated powinny mieć wszystkie metody „findViewById”? Jaki wzrost wydajności to powoduje? Czy przyspieszyłoby to przejścia?
android_student

Aby odpowiedzieć na pierwsze pytanie, onCreateViewsłuży do tworzenia hierarchii widoków fragmentu. Może to być spowodowane inflacją XML lub dynamicznym tworzeniem (tj. Programowym tworzeniem widoków Java). Więc możesz inflatew ogóle nie dzwonić . Ale powinieneś zwrócić widok nadrzędny, jeśli fragment musi mieć element interfejsu użytkownika. W przeciwnym razie wróć null.
orangemako

Nie ma żadnego wzrostu wydajności. Patrząc na FragmentManagerkod i fragment kodu dla performCreateView, który wywołuje onCreateView github.com/android/platform_frameworks_base/blob/… , masz gwarancję kilku rzeczy onViewCreated
oprócz

1. Hierarchia widoków zostanie dołączona do kontenera, jeśli fragment został dynamicznie dodany do jego aktywności nadrzędnej. 2. Możesz bezpiecznie wyszukiwać w widoku, nie martwiąc się o NPE. 3. Nie jestem zbyt zaznajomiony z animacjami, ale przejście fragmentów zostało już rozpoczęte (tj. Przesłane do kolejki komunikatów wątku interfejsu użytkownika).
orangemako

13

onCreateViewzwraca zawyżony widok. OnViewCreatedjest wywoływana zaraz po, onCreateViewa get ma parametr zawyżony widok. Typ zwracany tovoid


1
Dodałem edycję, aby wyjaśnić moje zamieszanie. Jeśli jedna metoda następuje zaraz po drugiej, dlaczego są dwie? Czy nie można stworzyć całego widoku za pomocą jednej metody, jak powyżej?
Smith

3
onCreateView powinien szybko wrócić. Na przykład OnViewCreate może służyć do wykonywania czynności inicjalizacyjnych. Jak powiedziałem, onViewCreated ma jako parametr View, który napompowałeś wewnątrz onCreateView. Możesz więc uniknąć getViewrozmowy
Blackbelt

8

onCreateView()jest odpowiednikiem fragmentu onCreate()dla działań i jest uruchamiany podczas tworzenia widoku.
onViewCreated()uruchamia się po utworzeniu widoku.

should I use one over the other for performance? NIE . Nie ma dowodów na wzrost wydajności.

W rzeczywistości istnieje onCreate()metoda we fragmentach, ale jest ona rzadko używana ( nigdy jej nie używam ani nie znajduję dla niej dobrego przypadku użycia).

Zawsze używam onCreateView()we Fragments jako zamiennika onCreate().
I jestem z tego zadowolony.


2
@npace, dlaczego? Myślę też, że onCreateViewjest to odpowiednik Activity onCreate.
CoolMind

2
@CoolMind Cóż, nPace nie jest całkowicie błędne, ponieważ onCreate()we Framents jest również metoda. Ale nigdy go nie używam (a przynajmniej nigdy go nie używam). Zawsze używam onCreateView()w Fragments jako zamiennika.
Phantômaxx

1
@Rotwang, zgadzam się z tobą! Niektóre samouczki używają onCreate do umieszczania setHasOptionsMenu (true), ale myślę, że lepiej byłoby to zrobić w onCreateView lub onViewCreated.
CoolMind

1
@CoolMind Całkowicie się zgadzam. Może użyłem złych słów w mojej odpowiedzi.
Phantômaxx

1
@Rotwang, powiedziałeś dobrze. Kiedy pierwszy raz użyłem fragmentów, nie wiedziałem też, dlaczego onCreate nie jest używany.
CoolMind

4

Dokumenty naFragment.onCreateView() razie mówią:

Zaleca się tylko zawyżanie układu w tej metodzie i przenoszenie logiki działającej na zwróconym widoku do onViewCreated (widok, pakiet).

Nie ma potrzeby, abyśmy rozumieli dlaczego; po prostu musimy zrobić tak, jak mówią doktorzy, ale byłoby interesujące wiedzieć, dlaczego takie zalecenie istnieje. Moim najlepszym przypuszczeniem jest oddzielenie obaw , ale IMHO to sprawia, że ​​jest to trochę bardziej skomplikowane, niż powinno.


Jeśli powodem jest oddzielenie obaw, to dlaczego Aktywność nadyma swój układ setContentView()w onCreate()?
Minh Nghĩa

@ MinhNghĩa Słuszna uwaga. Odpowiedzią na to pytanie może być po prostu to, że został zaprojektowany przez innego programistę myślącego inaczej (fragmenty zostały wprowadzone kilka lat po tym, jak po raz pierwszy dostaliśmy Androida), ale kto wie.
Peppe LG

2

Głównym powodem, dla którego chciałbym użyć, onViewCreatedjest to, że oddziela wszelką logikę inicjalizacji od logiki inflacji / tworzenia hierarchii widoku, która powinna zostać umieszczona w pliku onViewCreate. Wszystkie inne cechy wydajności wyglądają tak samo.


2

Myślę, że główna różnica między nimi polega na tym, że używasz kotlin.in onCreateView () za każdym razem, gdy chcesz uzyskać dostęp do widoku w pliku xml, powinieneś użyć findViewById, ale w onViewCreated możesz po prostu uzyskać dostęp do swojego widoku, po prostu wywołując jego identyfikator .


Czy to prawda? Otrzymuję wartość null dla widoku, jeśli po prostu użyję identyfikatora w kodzie w dowolny sposób. Muszę zawsze używać findViewById.
Jim Leask,

1
Nie, to nie jest .. oncreate view tworzy instancję widoku, onviewcreated jest wywoływany po oncreateview i przed przywróceniem zapisanych stanów ... jest to bardziej problem z synchronizacją w cyklu życia fragmentu
me_

1

onCreateView jest używany we fragmencie do tworzenia układu i powiększania widoku. onViewCreated służy do odwoływania się do widoku utworzonego powyższą metodą. Na koniec dobrą praktyką jest zdefiniowanie detektora akcji w onActivityCreated.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.