Perbedaan antara onCreateView dan onViewCreated di Fragment

119

Apa perbedaan mendasar antara kedua metode ini? Saat saya membuat TextView, haruskah saya menggunakan salah satu dari yang lain untuk kinerja?

Edit: Apa bedanya

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);
}
Smith
sumber
Saya menambahkan suntingan untuk menjelaskan kebingungan saya. Jika satu metode muncul tepat setelah yang lain, mengapa ada dua? Tidak bisakah semua pembuatan tampilan dilakukan dalam satu metode seperti di atas?
Smith
7
Jika Anda harus mencari di Google dan menebak, mungkin ada metode dengan nama yang salah.
Balázs Németh

Jawaban:

85

Kami menghadapi beberapa error saat memulai tampilan di onCreateView.

Anda harus memekarkan tata letak Anda onCreateViewtetapi tidak menginisialisasi tampilan lain menggunakan findViewByIddalam onCreateView.

Karena terkadang view tidak diinisialisasi dengan benar. Jadi selalu gunakan findViewByIddalam onViewCreated(saat tampilan sepenuhnya dibuat) dan ini juga meneruskan tampilan sebagai parameter.

onViewCreated adalah untuk memastikan bahwa tampilan sepenuhnya dibuat.

Dokumentasi android onViewCreated

Dipanggil segera setelah onCreateView( android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) dikembalikan, tetapi sebelum status tersimpan apa pun dipulihkan ke tampilan. Hal ini memberi kesempatan kepada subclass untuk menginisialisasi dirinya sendiri setelah mengetahui hierarki tampilannya telah dibuat sepenuhnya. Namun, hierarki tampilan fragmen tidak dilampirkan ke induknya pada saat ini.

Zar E Ahmer
sumber
4
Terima kasih. Saya juga menghadapi masalah ini dan menggunakan komponen. post(...) untuk menunggu sampai ditampilkan. Mungkin akan membuat findViewById dan inisialisasi lainnya di onViewCreated.
CoolMind
22
Dari mana teks itu dikutip? Saya tidak bisa menemukannya di dokumentasi resmi.
Daniel
Bisakah Anda memposting referensi dari situs Pengembang dari pernyataan yang dikutip di sini?
Namrata Bagerwal
4
Ini sebenarnya tidak benar. Anda bisa menemukan tampilan di onCreateView, tetapi hanya setelah Anda meluaskannya dan hanya dari tampilan yang sudah Anda luaskan. Fragment.findViewById () tidak aman, tetapi View.findViewById () aman jika Anda sudah meluaskan tampilan fragmen.
pengambilan gambar tanggal
46

onViewCreateddipanggil segera setelahnya onCreateView(metode Anda menginisialisasi dan membuat semua objek Anda, termasuk Anda TextView), jadi ini bukan masalah kinerja.

Dari situs pengembang:

onViewCreated (Tampilan tampilan, Bundle disimpanInstanceState)

Dipanggil segera setelah onCreateView (LayoutInflater, ViewGroup, Bundle) telah ditampilkan, tetapi sebelum status tersimpan apa pun dipulihkan ke tampilan. Hal ini memberi kesempatan kepada subclass untuk menginisialisasi dirinya sendiri setelah mengetahui hierarki tampilannya telah dibuat sepenuhnya. Namun, hierarki tampilan fragmen tidak dilampirkan ke induknya pada saat ini.

Sumber: Fragment # onViewCreated

u3l
sumber
28

Lebih baik melakukan tugas subview ke bidang di onViewCreated. Ini karena framework melakukan pemeriksaan null otomatis untuk Anda guna memastikan bahwa hierarki tampilan Fragmen Anda telah dibuat dan ditingkatkan (jika menggunakan file layout XML) dengan benar.

Cuplikan kode dari: 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);
}
orangemako
sumber
6
itu juga memisahkan logika inisialisasi apa pun dari hierarki tampilan logika inflasi / pembuatan
orangemako
1
Ini menarik, apakah Anda memiliki sumber tambahan tentang mengapa pendekatan ini lebih baik? Apakah itu berarti setiap metode onCreateView hanya boleh terdiri dari "return inflater.inflate (R.layout.layout_file, container, false);" dan onviewcreated harus memiliki semua metode "findViewById"? Peningkatan kinerja apa yang dihasilkannya? Apakah itu akan membuat transisi lebih cepat?
android_student
Untuk menjawab pertanyaan pertama Anda, onCreateViewdigunakan untuk membuat hierarki tampilan fragmen. Ini bisa melalui inflasi XML atau pembuatan dinamis (yaitu, membuat tampilan Java secara terprogram). Jadi, Anda mungkin tidak menelepon inflatesama sekali. Tetapi Anda harus mengembalikan beberapa tampilan induk jika fragmen tersebut perlu memiliki elemen UI. Jika tidak kembali null.
orangemako
Tidak ada peningkatan kinerja sama sekali. Melihat FragmentManagerkode fragmen dan performCreateView, yang memanggil onCreateView github.com/android/platform_frameworks_base/blob/… , Anda dijamin akan mendapatkan beberapa hal untuk onViewCreatedpanggilan balik siklus hidup:
orangemako
1. Hierarki tampilan akan dilampirkan ke penampung jika fragmen telah ditambahkan secara dinamis ke aktivitas induknya. 2. Anda dapat melakukan pencarian tampilan dengan aman tanpa mengkhawatirkan NPE. 3. Saya tidak begitu paham dengan animasi, tapi transisi fragmen sudah dimulai (yaitu, dikirim ke antrian pesan UI thread).
orangemako
13

onCreateViewmengembalikan tampilan yang meningkat. OnViewCreateddipanggil tepat setelah onCreateViewdan get memiliki parameter tampilan yang meningkat. Jenis kembalinya adalahvoid

Sabuk hitam
sumber
1
Saya menambahkan suntingan untuk menjelaskan kebingungan saya. Jika satu metode muncul tepat setelah yang lain, mengapa ada dua? Tidak bisakah semua pembuatan tampilan dilakukan dalam satu metode seperti di atas?
Smith
3
onCreateView akan kembali dengan cepat. OnViewCreate dapat digunakan untuk melakukan hal-hal inisialisasi, misalnya. Seperti yang saya katakan, onViewCreated memiliki parameter View yang Anda kembangkan di dalam onCreateView. Jadi, Anda dapat menghindari getViewpanggilan
Blackbelt
8

onCreateView()adalah Fragmen yang setara dengan onCreate()untuk Aktivitas dan dijalankan selama pembuatan Tampilan.
onViewCreated()berjalan setelah View dibuat.

should I use one over the other for performance? TIDAK . Tidak ada bukti peningkatan kinerja.

Sebenarnya ada onCreate()metode di Fragmen juga, tetapi jarang digunakan (saya tidak pernah menggunakannya, atau menemukan kasus penggunaan yang baik untuk itu).

Saya selalu menggunakan onCreateView()Fragmen sebagai pengganti onCreate().
Dan saya senang dengan itu.

Phantômaxx
sumber
2
@npace, mengapa? Saya juga berpikir onCreateViewitu setara dengan Aktivitas onCreate.
CoolMind
2
@CoolMind Nah, nPace tidak sepenuhnya salah, karena ada onCreate()metode di Framents juga. Tapi itu tidak pernah digunakan (atau, setidaknya, saya tidak pernah menggunakannya). Saya selalu menggunakan onCreateView()Fragmen sebagai pengganti.
Phantômaxx
1
@Rotwang, setuju denganmu! Beberapa tutorial menggunakan onCreate untuk meletakkan setHasOptionsMenu (true), tetapi saya pikir itu akan lebih baik dilakukan di onCreateView atau onViewCreated.
CoolMind
1
@ Cool Saya sangat setuju. Mungkin saya menggunakan kata-kata yang salah dalam jawaban saya.
Phantômaxx
1
@Rotwang, katamu benar. Saat saya menggunakan fragmen pertama kali, saya juga tidak tahu mengapa onCreate tidak digunakan.
CoolMind
4

Dokumen untukFragment.onCreateView() saat ini mengatakan:

Direkomendasikan untuk hanya memekarkan tata letak dalam metode ini dan memindahkan logika yang beroperasi pada Tampilan yang dikembalikan ke onViewCreated (View, Bundle).

Tidak perlu bagi kami untuk memahami mengapa; kami hanya perlu melakukan apa yang dikatakan oleh dokumen, tetapi akan menarik untuk mengetahui mengapa rekomendasi ini ada. Tebakan terbaik saya adalah pemisahan perhatian , tetapi IMHO ini membuatnya sedikit lebih rumit dari yang seharusnya.

Peppe LG
sumber
Jika alasannya adalah pemisahan keprihatinan, lalu mengapa Kegiatan mengembang tata letak di setContentView()dalam onCreate()?
Minh Nghĩa
@ Minhĩĩ Poin yang bagus. Jawaban atas pertanyaan itu bisa jadi itu dirancang oleh programmer yang berbeda dengan pemikiran yang berbeda (fragmen diperkenalkan beberapa tahun setelah kami pertama kali mendapatkan Android), tetapi siapa yang tahu.
Peppe LG
2

Alasan utama yang akan saya gunakan onViewCreatedadalah karena memisahkan logika inisialisasi apa pun dari hierarki tampilan logika inflasi / pembuatan yang harus masuk dalam file onViewCreate. Semua karakteristik kinerja lainnya terlihat sama.

AmeyaB
sumber
2

Saya pikir perbedaan utama antara ini adalah ketika Anda menggunakan kotlin.in onCreateView () setiap kali Anda ingin mengakses untuk melihat di file xml Anda, Anda harus menggunakan findViewById tetapi di onViewCreated Anda cukup mengakses ke tampilan Anda hanya dengan memanggil id-nya .

Shahriar enayaty
sumber
Apakah ini benar? Saya mendapatkan null untuk tampilan jika saya hanya menggunakan id dalam kode dengan cara apa pun. Saya harus selalu menggunakan findViewById.
Jim Leask
1
Tidak, bukan .. tampilan oncreate memberi contoh tampilan, onviewcreated dipanggil setelah oncreateview dan sebelum status yang disimpan dipulihkan ... ini lebih merupakan masalah waktu dalam siklus hidup fragmen
me_
1

onCreateView digunakan dalam fragmen untuk membuat tata letak dan meluaskan tampilan. onViewCreated digunakan untuk mereferensikan tampilan yang dibuat dengan metode di atas. Terakhir, adalah praktik yang baik untuk mendefinisikan pendengar tindakan di onActivityCreated.

Salu Khadka
sumber