Xác định thứ tự Z lượt xem của RelativeLayout trong Android


226

Tôi muốn xác định thứ tự z cho các lượt xem của RelativeLayout trong Android.

Tôi biết một cách để làm điều này là gọi bringToFront.

Có cách nào tốt hơn để làm điều này? Sẽ thật tuyệt nếu tôi có thể xác định thứ tự z trong bố cục xml.


4
View.bringToFront (); là anser
Shirish Herwade

Câu trả lời:


314

Cách đơn giản nhất chỉ đơn giản là chú ý đến thứ tự các Chế độ xem được thêm vào tệp XML của bạn. Thấp hơn trong tệp có nghĩa là cao hơn trong trục Z.

Chỉnh sửa: Điều này được ghi lại ở đâyở đây trên trang web của nhà phát triển Android. (Cảm ơn @flightplanner)


16
Thật không may, điều này không phải lúc nào cũng có thể thay đổi. Ví dụ: trong một bố cục tương đối, mỗi phần tử chỉ có thể được bố trí đối với các phần tử được xác định trước đó trong tệp
Casebash

67
Casebash, tôi không nghĩ rằng đó là trường hợp bạn chỉ cần sử dụng "@ + id / your_element_b Before_its_d xác định" và sau đó sử dụng cùng một id trong phần tử bạn xác định sau. Tôi có thể sai về điều này, những bố cục này rất khó đối với tôi, nhưng tôi chắc chắn có ấn tượng rằng nó hoạt động.
tjb

7
tjb là đúng (và tôi rất vui vì anh ấy). Sử dụng @ + id với lần đầu tiên đề cập đến id, ví dụ layout_above = "@ + id / some_id"
Michiel

3
Bạn cũng có thể đặt <item type = "id" name = "<your_id>" /> vào tệp xml giá trị và sau đó bạn có thể tham chiếu nó ở bất cứ đâu.
karl

8
Tôi biết tôi đến bữa tiệc muộn khoảng 3 năm, nhưng để trả lời @hpique, điều này được ghi lại ở đây
HexAndBugs

88

Nếu bạn muốn làm điều này trong mã, bạn có thể làm

View.bringToFront();

xem tài liệu


68

Xin lưu ý, các nút và các thành phần khác trong API 21 trở lên có độ cao lớn và do đó bỏ qua thứ tự xml của các phần tử bất kể bố cục chính. Mất một lúc để tìm ra cái đó.


16
Giải pháp cho lỗi này đối với tôi là gọi setElevation (1000) trên chế độ xem mà tôi muốn được hiển thị qua nút.
bắn vào lỗ

setElevation () yêu cầu API cấp 21
dp2050

21

Trong Android bắt đầu từ API cấp 21, các mục trong tệp bố cục nhận được thứ tự Z của chúng cả từ cách chúng được sắp xếp trong tệp, như được mô tả trong câu trả lời đúng và từ độ cao của chúng, giá trị độ cao cao hơn có nghĩa là mục đó có thứ tự Z cao hơn .

Điều này đôi khi có thể gây ra sự cố, đặc biệt là với các nút thường xuất hiện trên đầu các mục theo thứ tự của XML phải ở dưới chúng theo thứ tự Z. Để khắc phục điều này, chỉ cần đặtandroid:elevation mục trong XML bố cục của bạn khớp với thứ tự Z bạn muốn đạt được.

Nếu bạn đặt độ cao của một phần tử trong bố cục, nó sẽ bắt đầu tạo bóng. Nếu bạn không muốn hiệu ứng này, bạn có thể xóa bóng bằng mã như vậy:

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

Tôi chưa tìm thấy cách nào để loại bỏ bóng của chế độ xem nâng cao thông qua bố cục xml.


1
Như đã đề cập trong các ý kiến, bạn có thể sử dụng android:elevation="1000dp". Không có bóng được kết xuất theo cách này.
Vadim Kotov

15

Tôi gặp phải cùng một vấn đề: Trong một bố cục tương đối, tôi có 2 con childView1 và childView2. Đầu tiên, tôi đặt childView1 trên childView2 và tôi muốn childView1 nằm trên đầu của childView2. Thay đổi thứ tự quan điểm của trẻ em không giải quyết được vấn đề cho tôi. Điều làm việc cho tôi là đặt android: clipChildren = "false" trên ParentView và trong mã tôi đặt:

childView1.bringToFront();

parentView.invalidate();

2
Điều này đang hoạt động và Android làm tôi rất buồn. child.bringToFront()với parent.invalidate()các tác phẩm, nhưng parent.bringChildToFront(child)không. Đâu là logic mà tất cả chúng ta mong đợi từ một hệ điều hành?
Oliver Hausler

Để tạo hiệu ứng cho một số chế độ xem (bản dịch trong X và Y), tôi đã thử một số kết hợp cho linearLayout, FrameLayout và RelativeLayout nhưng luôn có vấn đề (liên quan đến chồng chéo hoặc không có kích thước tỷ lệ). Cuối cùng android:clipChildren="false"đã làm được mẹo. Cảm ơn bạn!
JCarlosR

15

Xin lưu ý rằng bạn có thể sử dụng view.setZ(float)bắt đầu từ API cấp 21. Tại đây bạn có thể tìm thêm thông tin.


13

Tôi nghĩ rằng tôi sẽ thêm một câu trả lời kể từ khi giới thiệu

android: dịchZ

Trường XML đã thay đổi mọi thứ một chút. Các câu trả lời khác đề nghị chạy

childView1.bringToFront();

parentView.invalidate();

Chúng tôi hoàn toàn chú ý đến EXCEPT vì mã này sẽ KHÔNG đưa childView1 ra trước bất kỳ chế độ xem nào với android được mã hóa cứng: dịchZ trong tệp XML. Tôi đã gặp vấn đề với điều này và một khi tôi đã xóa trường này khỏi các chế độ xem khác, bringToFront () hoạt động tốt.


điều này cũng đúng với android 5'selevation
shelll

5

API 21 đã view.setElevation(float)tích hợp sẵn

Sử dụng ViewCompat.setElevation(view, float);để tương thích ngược

Thêm phương pháp ViewCompat.setZ(v, pixels)ViewCompat.setTranslationZ(v, pixels)

Một cách khác để thu thập các nút hoặc xem mảng và sử dụng addViewđể thêm vào RelativeLayout




0

Kiểm tra xem bạn có bất kỳ độ cao nào trên một trong các Chế độ xem trong XML không. Nếu vậy, thêm độ cao cho các mục khác hoặc loại bỏ độ cao để giải quyết vấn đề. Từ đó, đó là thứ tự của các quan điểm chỉ ra những gì xuất hiện trên các quan điểm khác.


0

Hoặc đặt nút chồng chéo hoặc chế độ xem bên trong FrameLayout. Sau đó, RelativeLayout trong tệp xml sẽ tôn trọng thứ tự bố trí con khi chúng được thêm vào.


0

Bạn cũng có thể sử dụng mẫu mã bên dưới để đạt được điều tương tự

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

Điều này là tương thích ngược. Đây mCardViewlà một cái nhìn nên được dưới đây sourceView.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.