OnCreateView ve onViewCreated in Fragment Arasındaki Fark


119

Bu iki yöntem arasındaki temel fark nedir? Bir TextView oluşturduğumda, performans için birini diğerinin üzerinde kullanmalı mıyım?

Düzenleme: Aradaki fark nedir

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);
}

Kafa karışıklığımı açıklamak için bir düzenleme ekledim. Bir yöntem diğerinin hemen ardından gelirse, neden iki tane var? Tüm görünüm oluşturma, yukarıdaki gibi tek bir yöntemle yapılamaz mı?
Smith

7
Google'ı araştırmanız ve tahmin etmeniz gerekiyorsa, muhtemelen kötü adlandırılmış yöntemler vardır.
Balázs Németh

Yanıtlar:


85

Görünümünde başlatılırken bazı çökmelerle karşılaşıyoruz onCreateView.

Yerleşiminizi şişirmelisiniz, onCreateViewancak findViewByIdin kullanarak diğer görünümleri başlatmamalısınız onCreateView.

Çünkü bazen görünüm düzgün şekilde başlatılmıyor. Yani her zaman kullanmak findViewByIdiçinde onViewCreated(görünüm tamamen oluşturulduğunda) ve aynı zamanda parametre olarak görünümü geçer.

onViewCreated görünümün tamamen oluşturulduğundan emin olmaktır.

onViewCreated android Belgeleri

onCreateView( android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) Döndükten hemen sonra , ancak herhangi bir kaydedilmiş durum görünüme geri yüklenmeden önce çağrılır . Bu, alt sınıflara, görünüm hiyerarşilerinin tamamen yaratıldığını bildiklerinde kendilerini başlatma şansı verir. Ancak, parçanın görüş hiyerarşisi bu noktada üst kısmına bağlı değildir.


4
Teşekkürler. Ben de bu problemle karşılaştım ve bileşeni kullandım. post(...) gösterilinceye kadar bekleme yöntemi. Muhtemelen findViewById ve diğer başlatmaları onViewCreated.
CoolMind

22
Bu metin nereden alıntılandı? Resmi belgelerde bulamadım.
Daniel

Burada alıntılanan beyanın referansını Geliştirici sitesinden gönderebilir misiniz?
Namrata Bagerwal

4
Bu aslında doğru değil. Bir görünümü onCreateView'da bulabilirsiniz, ancak yalnızca onu şişirdikten sonra ve yalnızca zaten şişirdiğiniz görünümden. Fragment.findViewById () güvenli değildir, ancak parça görünümünü zaten şişirdiyseniz View.findViewById () güvenlidir.
colintheshots

46

onViewCreatedhemen sonra çağrılır onCreateView(sizin de dahil olmak üzere tüm nesnelerinizi başlattığınız ve oluşturduğunuz yöntem TextView), dolayısıyla bu bir performans meselesi değil.

Geliştirici sitesinden:

onViewCreated (Görünüm görünümü, Paket kaydedildiInstanceState)

OnCreateView (LayoutInflater, ViewGroup, Bundle) geri döndükten hemen sonra, ancak kaydedilmiş herhangi bir durum görünüme geri yüklenmeden önce çağrılır. Bu, alt sınıflara, görünüm hiyerarşilerinin tamamen yaratıldığını bildiklerinde kendilerini başlatma şansı verir. Ancak, parçanın görüş hiyerarşisi bu noktada üst kısmına bağlı değildir.

Kaynak: onViewCreated numaralı parça


28

İçindeki alanlara herhangi bir alt görünüm ataması yapmak daha iyidir onViewCreated. Bunun nedeni, Parçanızın görünüm hiyerarşisinin doğru şekilde oluşturulduğundan ve şişirildiğinden (eğer bir XML düzen dosyası kullanılıyorsa) emin olmak için çerçevenin sizin için otomatik bir boş denetim yapmasıdır.

Kod pasajı: 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
ayrıca herhangi bir başlatma mantığını görünüm hiyerarşisi enflasyon / yaratma mantığından
ayırır

1
Bu ilginç, bu yaklaşımın neden daha iyi olduğuna dair ek kaynaklarınız var mı? Bu, her onCreateView yönteminin yalnızca bir "dönüş inflater.inflate (R.layout.layout_file, container, false)" içermesi gerektiği anlamına mı geliyor? ve onviewcreated tüm "findViewById" yöntemlerine sahip olmalıdır? Bu nasıl bir performans artışı yaratır? Geçişleri daha hızlı hale getirir mi?
android_student

İlk sorunuzu cevaplamak için onCreateView, parçanın görünüm hiyerarşisini oluşturmak için kullanılır. Bu, XML şişirme veya dinamik oluşturma yoluyla olabilir (yani programatik olarak Java görünümleri oluşturma). Yani hiç arayamayabilirsiniz inflate. Ancak, parçanın bir UI öğesine sahip olması gerekiyorsa, bir üst öğe görünümü döndürmelisiniz. Aksi takdirde geri dönün null.
orangemako

Hiç bir performans artışı yok. Baktığımızda FragmentManageriçin ve parça kod performCreateViewçağırır, onCreateView github.com/android/platform_frameworks_base/blob/... , sizin için tho bir kaç şey garantilidir onViewCreatedyaşam döngüsü callback'inde:
orangemako

1. Parça, üst etkinliğine dinamik olarak eklenmişse, görünüm hiyerarşisi kapsayıcıya eklenecektir. 2. NPE'ler hakkında endişelenmeden, aramaları güvenle yapabilirsiniz. 3. Animasyonlara o kadar aşina değilim, ancak parça geçişi zaten başlamış olacak (yani, UI iş parçacığı mesaj kuyruğuna gönderilecek).
orangemako

13

onCreateViewşişirilmiş görünümü döndürür. OnViewCreatedhemen sonra çağrılır onCreateViewve get parametresi şişirilmiş görünüme sahiptir. Dönüş türüvoid


1
Kafa karışıklığımı açıklamak için bir düzenleme ekledim. Bir yöntem diğerinin hemen ardından gelirse, neden iki tane var? Tüm görünüm oluşturma, yukarıdaki gibi tek bir yöntemle yapılamaz mı?
Smith

3
onCreateView hızlı bir şekilde dönmelidir. OnViewCreate, örneğin başlatma işlemlerini gerçekleştirmek için kullanılabilir. Dediğim gibi, onViewCreated, onCreateView içinde şişirdiğiniz View parametresine sahiptir. Böylece getViewaramadan kaçınabilirsiniz
Blackbelt

8

onCreateView(), onCreate()Etkinlikler için Fragman eşdeğeridir ve Görünüm oluşturma sırasında çalışır . Görünüm oluşturulduktan sonra
onViewCreated() çalışır .

should I use one over the other for performance? HAYIR . Performans artışı olduğuna dair kanıt yok.

Aslında onCreate()Fragments'ta da bir yöntem var, ancak nadiren kullanılıyor ( asla kullanmıyorum ve bunun için iyi bir kullanım alanı bulmuyorum).

onCreateView()Parçalar'ı her zaman yerine kullanırım onCreate().
Ve bundan memnunum.


2
@npace, neden? Ayrıca onCreateViewAktivitelerin bir eşdeğeri olduğunu düşünüyorum onCreate.
CoolMind

2
@CoolMind Well, nPace tamamen değil bir onCreate()yöntem olduğu için nPace yanlış . Ama hiç kullanılmıyor (ya da en azından hiç kullanmıyorum). onCreateView()Parçalarda her zaman yedek olarak kullanırım .
Phantômaxx

1
@Rotwang, sana katılıyorum! Bazı öğreticiler setHasOptionsMenu (true) koymak için onCreate kullanır, ancak bence onCreateView veya onViewCreated'de daha iyi olur.
CoolMind

1
@CoolMind Tamamen katılıyorum. Belki cevabımda yanlış kelimeler kullandım.
Phantômaxx

1
@Rotwang, doğru dedin. Fragmanları ilk kez kullandığımda, onCreate'in neden kullanılmadığını da bilmiyordum.
CoolMind

4

Fragment.onCreateView()Şimdilik dokümanlar şöyle diyor:

Bu yöntemde yalnızca düzenin şişirilmesi ve döndürülen View üzerinde çalışan mantığın onViewCreated'e (View, Bundle) taşınması önerilir.

Nedenini anlamamıza gerek yok; sadece belgelerin söylediği gibi yapmamız gerekiyor, ancak bu tavsiyenin neden var olduğunu bilmek ilginç olurdu. En iyi tahminim endişenin ayrılmasıdır , ancak IMHO bu onu olması gerekenden biraz daha karmaşık hale getiriyor.


Nedeni endişe ayrılık ise, o zaman neden Aktivite kendi düzenini şişirmek yok setContentView()içinde onCreate()?
Minh Nghĩa

@ MinhNghĩa İyi nokta. Bu soruların cevabı basitçe, farklı bir programcı tarafından farklı düşünerek tasarlanması olabilir (parçalar, Android'i ilk edindikten birkaç yıl sonra tanıtıldı), ancak kim bilir.
Peppe LG

2

Kullanmamın ana nedeni onViewCreated, herhangi bir başlatma mantığını onViewCreate,. Diğer tüm performans özellikleri aynı görünüyor.


2

bence bunlar arasındaki temel fark, kotlin.in onCreateView () kullandığınız zamandır xml dosyanızda görüntülemek için her erişim sağlamak istediğinizde findViewById kullanmanız gerekir, ancak onViewCreated'de görünümünüze yalnızca kimliğini çağırarak erişebilirsiniz. .


Bu gerçekten doğru mu? Kimliği kodda her iki şekilde kullanırsam görünüm için boş alıyorum. Her zaman findViewById kullanmam gerekiyor.
Jim Leask

1
Hayır değil .. oncreate görünümü görünümü somutlaştırır, onviewcreated, oncreateview'den sonra ve kaydedilen durumlar geri yüklenmeden önce çağrılır ... bu daha çok parçanın yaşam döngüsündeki bir zamanlama sorunu
me_

1

onCreateView, düzen oluşturmak ve görünümü şişirmek için parçada kullanılır. onViewCreated, yukarıdaki yöntemle oluşturulan görünüme başvurmak için kullanılır. Son olarak, onActivityCreated içinde eylem dinleyicisini tanımlamak iyi bir uygulamadır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.