Peringatan "Hindari lewat nol sebagai root tampilan" ketika menggembungkan tampilan untuk digunakan oleh AlertDialog

126

Saya mendapatkan peringatan serat, Avoid passing null as the view rootketika menggembungkan pandangan dengan nullsebagai parent, seperti:

LayoutInflater.from(context).inflate(R.layout.dialog_edit, null);

Namun, tampilan akan digunakan sebagai konten dari AlertDialog, gunakan setViewpada AlertDialog.Builder, jadi saya tidak tahu apa yang harus dilewatkan sebagai parent.

Menurut Anda apa yang parentseharusnya dalam hal ini?

Randy Sugianto 'Yuku'
sumber
2
Pass false, bukan null. lihat ini
MrDumb
Cobalah untuk memberi Anda tata letak induk alih-alih nol dan kemudian jangan gunakan setView.
Haresh Chhelana
Saya menekan peringatan serat untuk metode ini. Saya belum melihat alasan yang bagus mengapa saya tidak boleh lulus null.
323go
4
Saya memahami masalah tata letak tergantung pada tampilan induk, tetapi itu tidak benar-benar berlaku untuk AlertDialog yang pada dasarnya melayang di atas hierarki tampilan Kegiatan. Itu sebabnya kamu bisa lulus null. Ada alasan mengapa Anda bisa menekan serat. Lint seharusnya memberi Anda peringatan untuk masalah yang sering tidak terjawab; dalam hal ini, itu permohonan yang benar.
323go
1
@ ashutiwari4 Saya belajar hal-hal baru yang baru setiap hari .. dunia yang indah: I
Rahul

Jawaban:

174

Gunakan kode ini untuk mengembang tampilan dialog tanpa peringatan:

View.inflate(context, R.layout.dialog_edit, null);
Edward Brey
sumber
7
@ MarianPaździoch Karena tidak menimbulkan peringatan. :-) Tentu saja, itu menimbulkan pertanyaan mengapa kode serat memperlakukan View.inflatedan LayoutInflator.inflateberbeda. Saya belum melihat jawaban yang pasti. Ini mungkin terkait dengan mengapa ada dua cara yang tampaknya setara untuk mengembang pandangan yang sama, yang saya juga tidak melihat alasan.
Edward Brey
12
Ini salah. Itu hanya menekan peringatan, tetapi masalahnya masih ada. Baca possiblemobile.com/2013/05/layout-inflation-as-intended untuk solusi yang lebih baik.
jcsahnwaldt Reinstate Monica
16
@JonaChristopherSahnwaldt Bisakah Anda menguraikan? Artikel itu mengatakan bahwa AlertDialog harus memiliki orangtua nol karena tidak memiliki tampilan root. Bagi saya ini sepertinya menegaskan bahwa peringatan itu masuk akal untuk pandangan di luar dialog tetapi tidak berlaku untuk tampilan dialog.
Edward Brey
7
@ EdwardBrey Anda benar - saya tidak membaca artikel secara menyeluruh. Dalam kasus khusus ini, tidak masalah menggunakan salah satu View.inflate(...null)atau @SuppressLint. Secara umum, LayoutInflater.from(...).inflate(..., parent, false)lebih baik. Terima kasih telah menunjukkan ini!
jcsahnwaldt Reinstate Monica
1
@Bevor That Hindari menyampaikan pertanyaan nol adalah tentang kasus di mana Anda memiliki orang tua. Pertanyaan ini tentang AlertDialog, yang tidak menyediakan induk untuk tampilan yang meningkat. Saat menggembungkan tampilan root dari sebuah AlertDialog, melewatkan null adalah benar. Lint tidak menjelaskan konteks khusus ini, jadi peringatan yang diberikannya jika Anda menggunakan fungsi yang mengambil parentfalse positive, bukan indikasi kesalahan apa pun rawan. Itu sebabnya valid dalam hal ini untuk menggunakan fungsi yang tidak mengambil parentdan tidak memicu peringatan.
Edward Brey
35

Ceritanya adalah bahwa ketika Anda menggelembungkan tampilan untuk dialog, parentharus nol, karena tidak diketahui pada waktu inflasi Lihat. Dalam hal ini, Anda memiliki tiga solusi dasar untuk menghindari peringatan:

  1. Menekan peringatan menggunakan @Suppress
  2. Mengembang View menggunakan metode mengembang View . Ini hanya pembungkus di sekitar LayoutInflater, dan sebagian besar hanya mengaburkan masalah.
  3. Mengembang View menggunakan LayoutInflater ini metode full : inflate(int resource, ViewGroup root, boolean attachToRoot). Setel attachToRootke false.Ini memberitahu inflater bahwa induknya tidak tersedia. Di versi Android Lint yang lebih lama, ini menghapus peringatan. Ini tidak lagi berlaku di Android Studio versi 1.0.

Lihat http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ untuk diskusi hebat tentang masalah ini, khususnya bagian "Setiap Aturan Memiliki Pengecualian" di bagian akhir.

emerssso
sumber
19

Casting nol saat ViewGroup menyelesaikan peringatan:

View dialogView = li.inflate(R.layout.input_layout,(ViewGroup)null);

di mana liadalah LayoutInflater'sobjek.

SVL Narasimham
sumber
di mana 'li' adalah objek LayoutInflater.
SVL Narasimham
3
Jawaban ini adalah yang terbaik, asalkan Anda mengerti MENGAPA Anda benar-benar melakukan ini. Ceritanya, seperti yang mungkin sudah Anda baca, adalah bahwa AlertDialog tidak mengenal orang tuanya pada waktu inflasi, dan itu adalah efek samping yang membuat orang melempar peringatan dalam situasi yang tepat ini ketika Anda benar-benar melakukan hal yang benar.
Bar Mar
Saya sudah membaca jawaban dan halaman yang tak terhitung jumlahnya tentang peringatan ini, tetapi solusi Anda adalah yang terbaik sejauh ini: sederhana dan elegan
Couitchy
9
Tapi itu adalah casting yang berlebihan
mohit
11
Lalu kita mendapatkan peringatan lain "Casting itu mubazir"!
Mousa
17

Anda harus menggunakan AlertDialog.Builder.setView(your_layout_id), jadi Anda tidak perlu mengembang.

Gunakan AlertDialog.findViewById(your_view_id)setelah membuat dialog.

Gunakan (AlertDialog) dialogInterfaceuntuk mendapatkan bagian dialogdalam OnClickListenerlalu dialog.findViewById(your_view_id).

Jeffrey Chen
sumber
1
Ini cara untuk pergi! Cukup buat dialog dan kemudian cari tampilan Anda.
user1806772
1
Ini adalah cara yang baik untuk melakukannya, namun ingatlah bahwa metode ini ditambahkan dalam API 21
Nicolás Carrasco
Bagaimana jika kita harus menyimpan tata letak yang meningkat ini dalam beberapa variabel? Sebagai contoh, saya menulis sebuah kelas Adi mana ada metode onCreateDialog. Dalam yang terakhir, saya menulis seperti kata Anda alert_dialog_builder.setView(R.layout.edit_account_dialog);. Tapi saya harus menyimpan tata letak yang meningkat ini dalam Avariabel atribut bernama the_inflated_layout_of_the_dialog.
JarsOfJam-Scheduler
9

Anda tidak perlu menentukan parentdialog.

Menekan penggunaan ini @SuppressLint("InflateParams")di bagian atas override.

kjdion84
sumber
7

Ketika Anda benar-benar tidak punya parent(misalnya membuat tampilan untuk AlertDialog), Anda tidak punya pilihan lain selain melewati null. Jadi lakukan ini untuk menghindari peringatan:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);
Mousa
sumber
4
Ini menghasilkan peringatan lain "nilai 'nullParent' selalu nol."
mallaudin
Pada AndroidStudio 3.3 dan API 28, ini adalah satu-satunya solusi dengan karya.
zeeshan
1
  1. AlertDialog sejauh yang saya tahu satu-satunya kasus adalah Anda dapat menggunakan null dengan aman daripada tampilan induk. Dalam hal ini Anda dapat menekan peringatan dengan menggunakan:

    @SuppressLint ("InflateParams")

  2. Secara umum Anda tidak boleh menggunakan SupressLint atau salah satu solusi yang disebutkan dalam jawaban lain untuk menghilangkan peringatan. Tampilan induk diperlukan untuk mengevaluasi Layout Params yang dideklarasikan di elemen root dari View yang digelembungkan. Itu berarti jika Anda menggunakan null alih-alih tampilan induk, semua Layout Params di elemen root akan diabaikan dan diganti dengan Layout Params default. Sebagian besar waktu itu akan baik-baik saja, tetapi dalam beberapa kasus ini akan menghasilkan bug yang sangat sulit ditemukan.

Apfelsaft
sumber
0

Dari dokumentasi View.inflate(), katanya

Mengembang tampilan dari sumber XML. Metode kenyamanan ini membungkus LayoutInflaterkelas, yang menyediakan berbagai pilihan untuk melihat inflasi.

  @param context The Context object for your activity or application.
  @param resource The resource ID to inflate
  @param root A view group that will be the parent.  Used to properly inflate the  layout_* parameters.
Divya Gupta
sumber
0

Menurut https://developer.android.com/guide/topics/ui/dialogs

Mengembang dan mengatur tata letak untuk dialog
Pass null sebagai tampilan induk karena terjadi di tata letak dialog

Oleh karena itu, untuk membuat AlertDialog, saya menggunakan @SuppressLint("InflateParams")

LayoutInflater inflater = requireActivity().getLayoutInflater();
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view);
Kor
sumber
-1

Alih-alih melakukan

view = inflater.inflate(R.layout.list_item, null);

melakukan

view = inflater.inflate(R.layout.list_item, parent, false);

Itu akan mengembang dengan orang tua yang diberikan, tetapi tidak akan melampirkannya ke orang tua.

Terima kasih banyak kepada Coeffect ( tautan ke posnya )

Kristen
sumber
Akan bermanfaat juga untuk mengetahui cara mendapatkan orang tua.
Johan Karlsson