คำเตือน“ หลีกเลี่ยงการส่ง null เป็นรูทมุมมอง” เมื่อขยายมุมมองเพื่อใช้โดย AlertDialog


126

ฉันได้รับการเตือนผ้าสำลี, Avoid passing null as the view rootเมื่อพองมุมมองกับnullเป็นparentเช่น:

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

อย่างไรก็ตามมุมมองจะถูกใช้เป็นเนื้อหาของ an AlertDialogโดยใช้setViewบนAlertDialog.Builderดังนั้นฉันไม่รู้ว่าควรส่งผ่านอะไรเป็นไฟล์parent.

คุณคิดว่าparentกรณีนี้ควรเป็นอย่างไร?


2
ส่งเท็จแทนค่าว่าง ดูสิ่งนี้
MrDumb

พยายามกำหนดเค้าโครงหลักให้คุณแทนค่าว่างจากนั้นอย่าใช้ setView
Haresh Chhelana

ฉันระงับคำเตือนผ้าสำลีสำหรับวิธีการนี้ nullผมยังไม่ได้เห็นเหตุผลว่าทำไมฉันไม่ควรผ่าน
323 ไป

4
ฉันเข้าใจปัญหาเลย์เอาต์ขึ้นอยู่กับมุมมองของผู้ปกครอง แต่นั่นไม่ได้ใช้กับ AlertDialog ซึ่งโดยพื้นฐานแล้วจะลอยอยู่เหนือลำดับชั้นมุมมองของกิจกรรม นั่นคือเหตุผลที่คุณผ่านnullมาได้ มีเหตุผลที่คุณสามารถระงับผ้าสำลีได้ ผ้าสำลีควรจะให้คำเตือนคุณสำหรับปัญหาที่มักจะพลาด ในกรณีนี้เป็นการร้องขอที่ถูกต้อง
323 ก.

1
@ ashutiwari4 ฉันเรียนรู้สิ่งใหม่ ๆ ทุกวัน .. โลกที่สวยงาม: ฉัน
ราหุล

คำตอบ:


175

ใช้รหัสนี้เพื่อขยายมุมมองกล่องโต้ตอบโดยไม่มีคำเตือน:

View.inflate(context, R.layout.dialog_edit, null);

7
@ MarianPaździochเพราะมันไม่ทำให้เกิดการเตือน. :-) ซึ่งแน่นอนว่า begs คำถามที่ว่าทำไมถือว่ารหัสผ้าสำลีView.inflateและLayoutInflator.inflateแตกต่างกัน ฉันไม่เห็นคำตอบที่ชัดเจน อาจเกี่ยวข้องกับสาเหตุที่มีสองวิธีที่ดูเหมือนจะเทียบเท่ากันในการขยายมุมมองเดียวกันโดยที่ฉันไม่เห็นเหตุผล
Edward Brey

12
นี่เป็นสิ่งที่ไม่ถูกต้อง เป็นการระงับการเตือนเท่านั้น แต่ปัญหายังคงมีอยู่ อ่านpossiblemobile.com/2013/05/layout-inflation-as-intendedสำหรับโซลูชันที่ดีกว่า
jcsahnwaldt Reinstate Monica

16
@JonaChristopherSahnwaldt ช่วยอธิบายได้ไหม บทความกล่าวว่า AlertDialog ควรมีแม่แบบว่างเนื่องจากไม่มีมุมมองรูท สำหรับฉันดูเหมือนว่าจะเป็นการตอกย้ำว่าคำเตือนนั้นเหมาะสมสำหรับมุมมองภายนอกกล่องโต้ตอบ แต่ไม่สามารถใช้ได้กับมุมมองไดอะล็อก
Edward Brey

7
@EdwardBrey คุณพูดถูก - ฉันไม่ได้อ่านบทความอย่างละเอียด ในกรณีนี้โดยเฉพาะอย่างยิ่งมันตกลงเพื่อการใช้งานอย่างใดอย่างหนึ่งหรือView.inflate(...null) @SuppressLintโดยทั่วไปLayoutInflater.from(...).inflate(..., parent, false)จะดีกว่า ขอบคุณที่ชี้ให้เห็น!
jcsahnwaldt Reinstate Monica

1
@Bevor ที่หลีกเลี่ยงการส่งคำถามว่างเป็นเรื่องเกี่ยวกับกรณีที่คุณมีผู้ปกครอง คำถามนี้เป็นคำถามเกี่ยวกับAlertDialogซึ่งไม่มีผู้ปกครองสำหรับการดูที่สูงเกินจริง เมื่อขยายมุมมองรูทของAlertDialogค่าว่างการส่งผ่านจะถูกต้อง ผ้าสำลีไม่ได้คำนึงถึงบริบทเฉพาะนี้ดังนั้นคำเตือนจะให้หากคุณใช้ฟังก์ชันที่parentให้ผลบวกเท็จไม่ใช่ข้อบ่งชี้ว่ามีข้อผิดพลาดเกิดขึ้นได้ง่าย นั่นเป็นเหตุผลว่าทำไมจึงถูกต้องในกรณีนี้ที่จะใช้ฟังก์ชันที่ไม่มีparentและไม่เรียกใช้คำเตือน
Edward Brey

35

เรื่องสั้นคือเมื่อคุณขยายมุมมองสำหรับกล่องโต้ตอบparentควรเป็นค่าว่างเนื่องจากไม่ทราบเวลาดูอัตราเงินเฟ้อ ในกรณีนี้คุณมีวิธีแก้ไขปัญหาพื้นฐานสามประการเพื่อหลีกเลี่ยงคำเตือน:

  1. ระงับคำเตือนโดยใช้ @Suppress
  2. พองดูโดยใช้มุมมองวิธีการพอง นี่เป็นเพียงกระดาษห่อหุ้มรอบ LayoutInflater และส่วนใหญ่เป็นเพียงแค่ทำให้ปัญหาสับสน
  3. พองดูโดยใช้ LayoutInflater ของวิธีการเต็มรูปแบบinflate(int resource, ViewGroup root, boolean attachToRoot) : ตั้งค่าattachToRootเป็นสิ่งfalseนี้เป็นการบอกให้พองตัวว่าไม่มีพาเรนต์ ใน Android Lint เวอร์ชันเก่าสิ่งนี้จะลบคำเตือนออกไป ไม่เป็นเช่นนั้นใน Android Studio เวอร์ชันหลัง 1.0 อีกต่อไป

ดูhttp://www.doubleencore.com/2013/05/layout-inflation-as-intended/สำหรับการสนทนาที่ดีเยี่ยมเกี่ยวกับปัญหานี้โดยเฉพาะในส่วน "ทุกกฎมีข้อยกเว้น" ในตอนท้าย


19

การแคสต์ null เป็น ViewGroup แก้ไขคำเตือน:

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

ที่liเป็นLayoutInflater'sวัตถุ


โดยที่ 'li' คือวัตถุ LayoutInflater
SVL Narasimham

3
คำตอบนี้ดีที่สุดโดยให้คุณเข้าใจว่าทำไมคุณถึงทำเช่นนี้จริง เรื่องสั้นอย่างที่คุณเคยอ่านมาคือ AlertDialog ไม่รู้จักผู้ปกครองเมื่อขยายเวลาดังนั้นจึงเป็นผลข้างเคียงที่ผ้าสำลีส่งคำเตือนในสถานการณ์ที่แม่นยำนี้เมื่อคุณทำในสิ่งที่ถูกต้อง
Mar Bar

ฉันได้อ่านคำตอบและหน้าเว็บเกี่ยวกับคำเตือนนี้นับไม่ถ้วน แต่วิธีแก้ปัญหาของคุณดีที่สุด: เรียบง่ายและสง่างาม
Couitchy

9
แต่เป็นการหล่อซ้ำซ้อน
mohit

11
จากนั้นเราจะได้รับคำเตือนอีกครั้งว่า "การแคสต์ซ้ำซ้อน"!
มูซา

17

คุณควรใช้AlertDialog.Builder.setView(your_layout_id)ดังนั้นคุณไม่จำเป็นต้องพองมัน

ใช้AlertDialog.findViewById(your_view_id)หลังจากสร้างไดอะล็อก

ใช้(AlertDialog) dialogInterfaceเพื่อให้ได้dialogภายในแล้วOnClickListenerdialog.findViewById(your_view_id)


1
นี่คือวิธีที่จะไป! เพียงสร้างกล่องโต้ตอบจากนั้นค้นหามุมมองของคุณ
user1806772

1
นี่เป็นวิธีที่ดี แต่อย่าลืมว่ามีการเพิ่มวิธีนี้ใน API 21
Nicolás Carrasco

จะเกิดอะไรขึ้นถ้าเราต้องเก็บเลย์เอาต์ที่สูงเกินจริงนี้ไว้ในตัวแปร? ยกตัวอย่างเช่นผมเขียนชั้นเรียนที่มีวิธีการA ในระยะหลังผมเขียนเป็นอูกล่าวว่าonCreateDialog alert_dialog_builder.setView(R.layout.edit_account_dialog);แต่ก็ต้องเก็บรูปแบบที่สูงขึ้นนี้ในAตัวแปรแอตทริบิวต์ 's the_inflated_layout_of_the_dialogชื่อ
JarsOfJam-Scheduler

9

คุณไม่จำเป็นต้องระบุparentสำหรับกล่องโต้ตอบ

ระงับสิ่งนี้โดยใช้@SuppressLint("InflateParams")ที่ด้านบนของการลบล้าง


7

เมื่อคุณจริงๆไม่ได้มีใด ๆparent(เช่นการสร้างมุมมองAlertDialog), nullคุณไม่มีทางเลือกอื่นนอกเหนือจากการส่งผ่าน ดังนั้นให้ทำเช่นนี้เพื่อหลีกเลี่ยงคำเตือน:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);

4
มันสร้างคำเตือนอีกคำเตือน "ค่า 'nullParent' เป็นโมฆะเสมอ"
mallaudin

สำหรับ AndroidStudio 3.3 และ API 28 นี่เป็นโซลูชันเดียวที่ใช้งานได้
zeeshan

1
  1. AlertDialog นั้นเท่าที่ฉันรู้มีเพียงกรณีเดียวคือคุณสามารถใช้nullแทนมุมมองหลักได้อย่างปลอดภัย ในกรณีนี้คุณสามารถระงับคำเตือนโดยใช้:

    @SuppressLint ( "InflateParams")

  2. โดยทั่วไปคุณไม่ควรใช้ SupressLint หรือวิธีแก้ปัญหาอย่างใดอย่างหนึ่งที่กล่าวถึงในคำตอบอื่น ๆ เพื่อกำจัดคำเตือน มุมมองพาเรนต์จำเป็นในการประเมิน Layout Params ซึ่งประกาศไว้ในองค์ประกอบรูทของ View ที่มีการขยาย นั่นหมายความว่าถ้าคุณใช้nullแทนมุมมองหลัก Layout Params ทั้งหมดในองค์ประกอบรากจะถูกละเว้นและแทนที่ด้วย Layout Params เริ่มต้น ส่วนใหญ่จะใช้ได้ดี แต่ในบางกรณีมันจะส่งผลให้เกิดบั๊กที่หาได้ยากจริงๆ


0

จากเอกสารView.inflate()ระบุว่า

ขยายมุมมองจากทรัพยากร XML วิธีอำนวยความสะดวกนี้ LayoutInflaterครอบคลุมชั้นเรียนซึ่งมีตัวเลือกมากมายสำหรับการดูอัตราเงินเฟ้อ

  @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.

0

อ้างอิงจากhttps://developer.android.com/guide/topics/ui/dialogs

ขยายและตั้งค่าเค้าโครงสำหรับกล่องโต้ตอบ
Pass null เป็นมุมมองหลักเนื่องจากอยู่ในเค้าโครงกล่องโต้ตอบ

ดังนั้นสำหรับการสร้าง AlertDialog ฉันใช้ @SuppressLint("InflateParams")

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

-1

แทนที่จะทำ

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

ทำ

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

มันจะพองตัวตามพ่อแม่ที่ให้มา แต่จะไม่ติดกับแม่

ขอบคุณมากสำหรับ Coeffect ( ลิงก์ไปยังโพสต์ของเขา )


นอกจากนี้ยังจะมีประโยชน์หากทราบวิธีรับผู้ปกครอง
Johan Karlsson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.