Menentukan urutan tampilan RelativeLayout di Android

226

Saya ingin menentukan urutan z tampilan RelativeLayout di Android.

Saya tahu satu cara untuk melakukan ini adalah menelepon bringToFront.

Apakah ada cara yang lebih baik untuk melakukan ini? Akan lebih bagus jika saya bisa mendefinisikan urutan z dalam tata letak xml.

hpique
sumber
4
View.bringToFront (); is the anser
Shirish Herwade

Jawaban:

314

Cara termudah adalah dengan memperhatikan urutan di mana Tampilan ditambahkan ke file XML Anda. Turun ke bawah dalam file berarti lebih tinggi di sumbu Z.

Sunting: Ini didokumentasikan di sini dan di sini di situs pengembang Android. (Terima kasih @flightplanner)

Steve Haley
sumber
16
Sayangnya ini tidak selalu memungkinkan untuk diubah. Misalnya, dalam tata letak yang relatif, masing-masing elemen hanya dapat ditata sehubungan dengan yang sebelumnya ditentukan dalam file
Casebash
67
Casebash, saya tidak berpikir itu perlu kasus Anda hanya perlu menggunakan "@ + id / your_element_before_its_defined" dan kemudian gunakan id yang sama dalam elemen yang Anda tetapkan nanti. Saya mungkin salah tentang ini, tata letak ini sangat rumit bagi saya, tetapi saya pasti mendapat kesan bahwa itu berhasil.
tjb
7
tjb benar (dan aku senang dia). Gunakan @ + id dengan penyebutan id pertama misalnya layout_above = "@ + id / some_id"
Michiel
3
Anda juga dapat memasukkan <item type = "id" name = "<your_id>" /> ke file nilai xml, dan kemudian Anda dapat merujuknya di mana saja.
karl
8
Saya tahu saya terlambat sekitar 3 tahun ke pesta, tetapi sebagai jawaban untuk @hpique, ini didokumentasikan di sini
HexAndBugs
88

Jika Anda ingin melakukan ini dalam kode Anda dapat melakukannya

View.bringToFront();

lihat dokumen

QAMAR
sumber
68

Harap perhatikan, tombol dan elemen lain di API 21 dan yang lebih tinggi memiliki elevasi tinggi, dan karenanya mengabaikan urutan elemen xml terlepas dari tata letak induk. Butuh waktu beberapa saat untuk memikirkannya.

Daniel Wilson
sumber
16
solusi untuk bug ini bagi saya adalah memanggil setElevation (1000) pada tampilan yang ingin saya render di atas tombol.
Api di lubang
setElevation () membutuhkan API level 21
dp2050
21

Di Android mulai dari API level 21, item dalam file tata letak mendapatkan urutan Z baik dari cara mereka memesan dalam file, seperti yang dijelaskan dalam jawaban yang benar, dan dari ketinggiannya, nilai elevasi yang lebih tinggi berarti item mendapat urutan Z yang lebih tinggi .

Ini kadang-kadang dapat menyebabkan masalah, terutama dengan tombol yang sering muncul di atas item yang menurut urutan XML harus di bawah mereka dalam urutan Z. Untuk memperbaikinya, cukup atur android:elevationitem di tata letak XML agar sesuai dengan urutan Z yang ingin Anda capai.

Jika Anda mengatur ketinggian elemen dalam tata letak itu akan mulai menimbulkan bayangan. Jika Anda tidak ingin efek ini, Anda dapat menghapus bayangan dengan kode seperti ini:

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

Saya belum menemukan cara untuk menghapus bayangan tampilan yang ditinggikan melalui tata letak xml.

Lejonl
sumber
1
Seperti disebutkan dalam komentar, Anda dapat menggunakan android:elevation="1000dp". Tidak ada bayangan yang ditampilkan dengan cara ini.
Vadim Kotov
15

Saya mengalami masalah yang sama: Di parentView tata letak relatif, saya punya 2 anak childView1 dan childView2. Pada awalnya, saya meletakkan childView1 di atas childView2 dan saya ingin childView1 berada di atas childView2. Mengubah urutan pandangan anak-anak tidak memecahkan masalah bagi saya. Apa yang berhasil bagi saya adalah mengatur android: clipChildren = "false" pada parentView dan dalam kode yang saya set:

childView1.bringToFront();

parentView.invalidate();
Tony Vu
sumber
2
Ini berfungsi, dan Android membuat saya sangat sedih. child.bringToFront()dengan parent.invalidate()karya, tetapi parent.bringChildToFront(child)tidak. Di mana logika yang kita semua harapkan dari OS?
Oliver Hausler
Untuk menghidupkan beberapa tampilan (terjemahan dalam X dan Y), saya mencoba beberapa kombinasi untuk LinearLayout, FrameLayout dan RelativeLayout tetapi selalu ada masalah (terkait dengan tumpang tindih atau ukuran tidak proporsional). Akhirnya android:clipChildren="false"berhasil. Terima kasih!
JCarlosR
15

Harap perhatikan bahwa Anda dapat menggunakan view.setZ(float)mulai dari API level 21. Di sini Anda dapat menemukan lebih banyak info.

Vadim Kotov
sumber
13

Saya pikir saya akan menambahkan jawaban sejak diperkenalkannya

android: translationZ

Bidang XML mengubah sedikit hal. Jawaban lain yang menyarankan berjalan

childView1.bringToFront();

parentView.invalidate();

benar-benar tepat KECUALI untuk itu kode ini TIDAK akan membawa childView1 di depan tampilan apa pun dengan android hardcoded: translationZ dalam file XML. Saya mengalami masalah dengan ini, dan begitu saya menghapus bidang ini dari pandangan lain, bringToFront () bekerja dengan baik.

ThePartyTurtle
sumber
ini juga berlaku untuk android 5'selevation
shelll
5

API 21 memiliki fitur view.setElevation(float)bawaan

Gunakan ViewCompat.setElevation(view, float);untuk kompatibilitas mundur

Lebih banyak metode ViewCompat.setZ(v, pixels)danViewCompat.setTranslationZ(v, pixels)

Cara lain mengumpulkan tombol atau melihat array dan gunakan addViewuntuk menambah RelativeLayout

Qamar
sumber
1

Anda dapat menggunakan kustom RelativeLayoutdengan didefinisikan ulang

protected int getChildDrawingOrder (int childCount, int i)

Sadarilah - metode ini menggunakan param isebagai "tampilan yang harus saya gambar i'th". Beginilah cara ViewPagerkerjanya. Ini mengatur urutan gambar kustom dalam hubungannya dengan PageTransformer.

Petrov Dmitrii
sumber
0

Periksa apakah Anda memiliki ketinggian pada salah satu Tampilan di XML. Jika demikian, tambahkan elevasi ke item lain atau hapus elevasi untuk menyelesaikan masalah. Dari sana, urutan pandanganlah yang menentukan apa yang muncul di atas yang lain.

The Fluffy T Rex
sumber
0

Atau letakkan tombol yang tumpang tindih atau tampilan di dalam FrameLayout. Kemudian, RelativeLayout dalam file xml akan menghormati urutan tata letak anak saat ditambahkan.

Badr
sumber
0

Anda dapat menggunakan contoh kode di bawah ini juga untuk mencapai hal yang sama

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

Ini kompatibel ke belakang. Berikut mCardViewini adalah tampilan yang harus di bawah ini sourceView.

Ankit
sumber