การกำหนดลำดับการดู Z ของ RelativeLayout ใน Android


226

ฉันต้องการกำหนดลำดับ z ของมุมมองของ RelativeLayout ใน Android

bringToFrontฉันรู้ว่าวิธีหนึ่งในการทำเช่นนี้จะเรียก

มีวิธีที่ดีกว่าในการทำเช่นนี้? มันจะดีมากถ้าฉันสามารถกำหนดลำดับ z ในโครงร่าง xml


4
View.bringToFront (); คือ anser
Shirish Herwade

คำตอบ:


314

วิธีที่ง่ายที่สุดคือเพียงใส่ใจกับลำดับที่เพิ่มจำนวนการดูไปยังไฟล์ XML ของคุณ ลดลงในไฟล์หมายถึงสูงขึ้นในแกน Z

แก้ไข: เอกสารนี้ที่นี่และที่นี่บนเว็บไซต์นักพัฒนาซอฟต์แวร์ Android (ขอบคุณ @flightplanner)


16
สิ่งนี้ไม่สามารถเปลี่ยนแปลงได้เสมอไป ตัวอย่างเช่นในโครงร่างสัมพัทธ์แต่ละองค์ประกอบสามารถเลย์เอาต์ได้เฉพาะส่วนที่กำหนดไว้ก่อนหน้าในไฟล์
Casebash

67
Casebash ฉันไม่คิดว่าจำเป็นต้องใช้กรณีที่คุณต้องใช้ "@ + id / your_element_before_its_defined" จากนั้นใช้รหัสเดียวกันในองค์ประกอบที่คุณกำหนดในภายหลัง ฉันอาจจะผิดเกี่ยวกับเรื่องนี้เลย์เอาต์เหล่านี้เป็นเรื่องยากสำหรับฉัน แต่ฉันได้รับความประทับใจอย่างแน่นอน
tjb

7
tjb ถูกต้อง (และฉันดีใจที่เขาเป็น) ใช้ @ + id ด้วยการกล่าวถึง ID ครั้งแรกเช่น layout_above = "@ + id / some_id"
Michiel

3
คุณยังสามารถใส่ <item type = "id" name = "<your_id>" /> ลงในไฟล์ค่า xml จากนั้นคุณสามารถอ้างอิงได้ทุกที่
karl

8
ฉันรู้ว่าฉันไปงานเลี้ยงประมาณ 3 ปี แต่คำตอบของ @hpique นี่เป็นเอกสารที่นี่
HexAndBugs


68

โปรดทราบว่าปุ่มและองค์ประกอบอื่น ๆ ใน API 21 และสูงกว่านั้นมีระดับความสูงที่สูงและดังนั้นจึงไม่สนใจลำดับขององค์ประกอบ xml โดยไม่คำนึงถึงเค้าโครงหลัก เอาฉันสักครู่เพื่อหาอันนั้น


16
วิธีแก้ไขข้อผิดพลาดสำหรับฉันนี้คือการเรียก setElevation (1,000) ในมุมมองที่ฉันต้องการจะแสดงผลผ่านปุ่ม
ไฟไหม้ในหลุม

setElevation () ต้องการ API ระดับ 21
dp2050

21

ใน Android ที่เริ่มต้นจาก API ระดับ 21 รายการในไฟล์เลย์เอาต์จะได้รับลำดับ Z ทั้งสองจากวิธีการสั่งซื้อภายในไฟล์ดังที่อธิบายไว้ในคำตอบที่ถูกต้องและจากระดับความสูงค่าระดับความสูงที่สูงขึ้นหมายถึงรายการนั้น .

บางครั้งสิ่งนี้อาจทำให้เกิดปัญหาโดยเฉพาะอย่างยิ่งกับปุ่มที่มักปรากฏอยู่ด้านบนของรายการที่เรียงตามลำดับของ XML ควรอยู่ด้านล่างตามลำดับ Z ในการแก้ไขปัญหานี้เพียงกำหนดandroid:elevationรายการในเลย์เอาต์ XML ของคุณเพื่อให้ตรงกับคำสั่ง Z ที่คุณต้องการ

ฉันคุณตั้งค่าระดับความสูงขององค์ประกอบในเค้าโครงมันจะเริ่มร่ายเงา หากคุณไม่ต้องการเอฟเฟกต์นี้คุณสามารถลบเงาด้วยโค้ดดังนี้:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   myView.setOutlineProvider(null);
}

ฉันไม่พบวิธีลบเงาของมุมมองที่ยกระดับผ่านเลย์เอาท์ xml


1
android:elevation="1000dp"ตามที่ระบุไว้ในความคิดเห็นที่คุณสามารถใช้ ไม่มีเงาใด ๆ แสดงผลในลักษณะนี้
Vadim Kotov

15

ฉันพบปัญหาเดียวกัน: ในโครงร่างที่เป็น parent parentView ฉันมีลูก 2 คน childView1 และ childView2 ตอนแรกฉันวาง childView1 เหนือ childView2 และฉันต้องการ childView1 ให้อยู่ด้านบนของ childView2 การเปลี่ยนลำดับการดูเด็กไม่ได้แก้ปัญหาสำหรับฉัน สิ่งที่ใช้ได้ผลสำหรับฉันคือตั้งค่าandroid: clipChildren = "false"บน parentView และในรหัสที่ฉันตั้งไว้:

childView1.bringToFront();

parentView.invalidate();

2
มันใช้งานได้และ Android ทำให้ฉันเสียใจมาก child.bringToFront()กับparent.invalidate()งาน แต่parent.bringChildToFront(child)ไม่ ตรรกะที่เราทุกคนคาดหวังจากระบบปฏิบัติการอยู่ที่ไหน
Oliver Hausler

เพื่อให้ภาพเคลื่อนไหวบางมุมมอง (การแปลใน X และ Y) ฉันลองชุดค่าผสมหลายแบบสำหรับ LinearLayout, FrameLayout และ RelativeLayout แต่มีปัญหาอยู่เสมอ (เกี่ยวข้องกับการทับซ้อนหรือไม่ได้สัดส่วน) ในที่สุดandroid:clipChildren="false"ก็ทำการหลอกลวง ขอบคุณ!
JCarlosR

15

โปรดทราบว่าคุณสามารถใช้view.setZ(float)เริ่มต้นจาก API ระดับ 21 ที่นี่คุณสามารถค้นหาข้อมูลเพิ่มเติมได้


13

คิดว่าฉันจะเพิ่มคำตอบตั้งแต่การเปิดตัว

หุ่นยนต์: translationZ

ฟิลด์ XML เปลี่ยนสิ่งต่าง ๆ เป็นตาด คำตอบอื่น ๆ ที่แนะนำให้ทำงาน

childView1.bringToFront();

parentView.invalidate();

มีข้อยกเว้นทั้งหมดสำหรับรหัสนี้ที่จะไม่นำ childView1 ต่อหน้ามุมมองใด ๆ ที่มี android hardcoded: translateZ ในไฟล์ XML ฉันมีปัญหากับสิ่งนี้และเมื่อฉันลบฟิลด์นี้จากมุมมองอื่น bringToFront () ก็ใช้งานได้ดี


นี่เป็นความจริงสำหรับ android 5's ด้วยelevation
shelll

5

API 21 มีview.setElevation(float)บิลด์อิน

ใช้ViewCompat.setElevation(view, float);สำหรับความเข้ากันได้ย้อนหลัง

วิธีการเพิ่มเติมViewCompat.setZ(v, pixels)และViewCompat.setTranslationZ(v, pixels)

อีกวิธีหนึ่งในการรวบรวมปุ่มหรือดูอาร์เรย์และใช้addViewเพื่อเพิ่มไปยัง RelativeLayout


4

childView.bringToFront () ไม่ได้ผลสำหรับฉันดังนั้นฉันจึงตั้งค่าการแปล Z ของรายการที่เพิ่มล่าสุดอย่างน้อยที่สุด (รายการที่ซ้อนทับเด็กคนอื่น ๆ ทั้งหมด) เป็นค่าลบดังนี้:

lastView.setTranslationZ(-10);

ดูhttps://developer.android.com/reference/android/view/View.html#setTranslationZ(float)สำหรับข้อมูลเพิ่มเติม


1

คุณสามารถใช้กำหนดเองRelativeLayoutกับนิยามใหม่

protected int getChildDrawingOrder (int childCount, int i)

โปรดระวัง - วิธีนี้ใช้พารามิเตอร์iเป็น "ฉันควรวาดภาพi'thไหน" นี่คือวิธีการViewPagerทำงาน PageTransformerมันชุดคำสั่งที่กำหนดเองวาดภาพร่วมกับ


0

ตรวจสอบว่าคุณมีการยกระดับใด ๆ ของหนึ่งใน Views ใน XML ถ้าเป็นเช่นนั้นเพิ่มระดับความสูงให้กับรายการอื่นหรือลบระดับความสูงเพื่อแก้ไขปัญหา จากตรงนั้นมันเป็นลำดับของมุมมองที่กำหนดสิ่งที่อยู่เหนือสิ่งอื่น


0

หรือวางปุ่มที่ทับซ้อนกันหรือมุมมองภายใน FrameLayout จากนั้น RelativeLayout ในไฟล์ xml จะเคารพลำดับของเลย์เอาต์ลูกที่เพิ่มเข้ามา


0

คุณสามารถใช้ตัวอย่างโค้ดด้านล่างได้เช่นเดียวกัน

ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);

สิ่งนี้เข้ากันได้ย้อนหลัง นี่เป็นมุมมองที่ควรจะต่ำกว่าmCardViewsourceView

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