Bagaimana cara menghadirkan tampilan di depan segalanya?


130

Saya memiliki aktivitas dan banyak widget di dalamnya, beberapa dari mereka memiliki animasi dan karena animasi beberapa widget bergerak (menerjemahkan) satu sama lain. Misalnya tampilan teks bergerak di beberapa tombol. . .

Sekarang masalahnya adalah saya ingin tombol selalu di depan. Dan ketika textview bergerak, saya ingin bergerak di belakang tombol.

Saya tidak dapat mencapai ini, saya mencoba semua yang saya tahu, dan "bringToFront ()" pasti tidak berfungsi.

perhatikan saya tidak ingin mengontrol z-order dengan urutan menempatkan elemen ke tata letak karena saya tidak bisa :), tata letak yang kompleks dan saya tidak dapat menempatkan semua tombol di mengemis tata letak


3
Saya menggunakan RelativeLayoutdengan tampilan "atas" muncul terakhir di XML. Lihat stackoverflow.com/a/31340762/1121497
Ferran Maylinch

Adakah yang bisa tolong beri tahu kode terkait dalam xml 'bringToFront'
Shirish Herwade

Coba gunakan elevasi bottomView = elevasi: 1dp dan topView = elevasi: 2dp di xml Anda || ViewCompat.setElevation (Lihat, int)
Tlacaelel Ramon Luis

Jawaban:


144

Anda dapat memanggil bringToFront () pada tampilan yang Anda inginkan di depan

Ini adalah sebuah contoh:

    yourView.bringToFront();

4
Hasil yang tidak terduga: Saya menggunakan tata letak linier vertikal dan tampilan yang dibawa ke depan muncul di bagian bawah ... Sebagai contoh, saya telah A / B / Cdan ingin membawa Ake depan, jadi setelah berlari a.bringToFront()saya berakhir dengan tata letak seperti B / C / A.
Ferran Maylinch

2
Jadi saya menemukan LinearLayouttidak dapat digunakan dengan bringToFront. Saya akhirnya menggunakan RelativeLayout. Lihat komentar saya pada pertanyaan itu sendiri.
Ferran Maylinch

1
Adakah yang bisa tolong beri tahu kode terkait dalam xml 'bringToFront'
Shirish Herwade

Ini menghasilkan penempatan ulang elemen yang saya pindahkan ke depan untuk alasan apa pun. ViewCompat.setTranslationZ(view, 1)bekerja dengan baik di sisi lain.
Bimde

1
jika saya digunakan dalam manifes android: theme = "@ android: style / Theme.Light.NoTitleBar" dalam aktivitas daripada yourView.bringToFront (); berfungsi dengan baik, tetapi saya menggunakan android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); tidak bekerja Petunjuk apa pun tentang itu.
Rahul

42

Saya telah mencari-cari stack overflow untuk menemukan jawaban yang bagus dan ketika saya tidak dapat menemukan jawabannya, saya mencari melalui dokumen.

sepertinya belum ada yang menemukan jawaban sederhana ini:

ViewCompat.setTranslationZ(view, translationZ);

terjemahan default z adalah 0.0


Itu adalah posisi elemen pada sumbu Z di px, juga dikenal sebagai ketinggian. setTranslationX akan menggerakkan tampilan sepanjang sumbu X (kiri / kanan), setTranslationY sepanjang sumbu Y (atas / bawah). Sumbu Z adalah sumbu ke-3.
xdevs23

Bagaimana dengan setZ()? Jika saya ingat dengan benar, posisi Z pada tampilan adalah elevasinya ditambah terjemahannya Z, setelah semua.
Gensoukyou1337

2
@ Gensoukyou1337, maka ViewCompat.setZ(view, yourValueInPixels); view.setZ()hanya berfungsi pada API 21 dan lebih tinggi.
Johnny Five

1
Memeriksa kode Java 8 di Android Studio - hanya memeriksa apakah SDK_INT> = 21, jadi untuk <21 api tidak berpengaruh.
Vadim

32

Solusi yang lebih sederhana adalah dengan mengedit XML aktivitas. Menggunakan

android:translationZ=""

3
Ini hanya berguna di Android API 21 atau lebih tinggi.
isakbob

25

bringToFront()adalah cara yang benar, tetapi, CATATAN bahwa Anda harus menelepon bringToFront()daninvalidate() metode pada tampilan tingkat tertinggi (di bawah tampilan root Anda), misalnya:

Hirarki tampilan Anda adalah:

-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6

Jadi, ketika Anda menghidupkan kembali tombol Anda (1-> 6), tombol Anda akan berada di bawah (di bawah) ImageView. Untuk membawanya (di atas), ImageViewAnda harus memanggil bringToFront()dan invalidate()metode pada Anda LinearLayout. Maka itu akan bekerja :) ** CATATAN: Ingatlah untuk mengatur android:clipChildren="false"tata letak root Anda atau gradparent_layout tampilan-animate. Mari kita lihat kode asli saya:

.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hw="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_theme_color"
    android:orientation="vertical" >

    <com.binh.helloworld.customviews.HWActionBar
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_actionbar_height"
        android:layout_alignParentTop="true"
        hw:titleText="@string/app_name" >
    </com.binh.helloworld.customviews.HWActionBar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/action_bar"
        android:clipChildren="false" >

        <LinearLayout
            android:id="@+id/layout_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>

        <ImageView
            android:id="@+id/imgv_main"
            android:layout_width="@dimen/common_imgv_height"
            android:layout_height="@dimen/common_imgv_height"
            android:layout_centerInParent="true"
            android:contentDescription="@string/app_name"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

Beberapa kode dalam .java

private LinearLayout layoutTop, layoutBottom;
...
layoutTop = (LinearLayout) rootView.findViewById(R.id.layout_top);
layoutBottom = (LinearLayout) rootView.findViewById(R.id.layout_bottom);
...
//when animate back
//dragedView is my layoutTop's child view (i added programmatically) (like buttons in above example) 
dragedView.setVisibility(View.GONE);
layoutTop.bringToFront();
layoutTop.invalidate();
dragedView.startAnimation(animation); // TranslateAnimation
dragedView.setVisibility(View.VISIBLE);

Gluck!


bagaimana jika Anda hanya ingin membawa tombol 6 di atas imageview dan bukan tombol lainnya?
Adam Katz

@AdamKatz: Saya pikir Anda harus mengatur ulang mereka menjadi kepalan level lain. Kemudian, bawa jalan Anda.
Justin

terima kasih saya mencoba membawa hanya satu item dari tampilan pendaur ulang di atas tampilan tetapi meninggalkan item lain di bawahnya, cukup macet!
Adam Katz

Saya menggunakan hal yang sama. Ini berfungsi dengan baik dengan satu masalah yang menyembunyikan bilah alat.
user2980181

Apakah ini bekerja dengan beberapa level? Katakanlah saya memiliki ConstraintLayoutyang berisi RelativeLayout, dan yang lainnya RelativeLayout, keduanya memiliki ukuran yang sama dengan akarnya ConstraintLayout( match_parent). Yang pertama RelativeLayoutmemiliki Button, dan juga di belakang (z-order-wise) yang kedua RelativeLayout. Bisakah saya membuat yang Buttonpertama RelativeLayoutmuncul seolah-olah itu di atas segalanya, sehingga terlihat dan dapat diklik, menggunakan View::bringToFront()?
oaskamay

25

Dengan kode ini dalam xml

 android:translationZ="90dp"

3
Dari mana 90dpdatangnya?
Sudhir Khanger

1
ini adalah entri manual. Anda dapat mencoba berdasarkan kebutuhan Anda. baik 45dp atau 135dp atau 180dp atau 270dp
Krishna

Tidak bisakah Anda menggunakan 1dp saja?
Tyler Turnbull

18

Coba FrameLayout, ini memberi Anda kemungkinan untuk menempatkan pandangan satu di atas yang lain. Anda dapat membuat dua LinearLayouts: satu dengan tampilan latar belakang, dan satu dengan tampilan latar depan, dan menggabungkannya menggunakan FrameLayout. Semoga ini membantu.


1
Bagaimana kita bisa membawanya ke atas seperti dialog?
Gaurav Arora

@Infinity, Anda dapat membuat FragmentDialog untuk tujuan ini, atau cukup gunakan Theme.Dialog untuk Aktivitas Anda.
Egor

Saya tidak dapat menggunakan FragmentDialog karena tidak kompatibel untuk API 10. Kedua, saya sudah menggunakan tema untuk aplikasi saya. Apakah ada cara lain? Saya sudah menggunakannya FrameLayout seperti yang Anda katakan!
Gaurav Arora

@Infinity, Anda dapat menggunakan versi pustaka kompatibilitas dari FragmentDialog, yang tersedia dari API 4.
Egor

8

Jika Anda menggunakan ConstraintLayout, cukup letakkan elemen setelah elemen lain untuk membuatnya di depan daripada yang lain



3

Mungkin ada cara lain yang menyelamatkan hari itu. Hanya init Dialog baru dengan tata letak yang diinginkan dan hanya menunjukkannya. Saya membutuhkannya untuk menampilkan loadingView melalui DialogFragment dan ini adalah satu-satunya cara saya berhasil.

Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();

bringToFront () mungkin tidak berfungsi dalam beberapa kasus seperti milik saya. Tetapi konten tata letak dialog_top harus menimpa apa pun di lapisan ui. Tapi bagaimanapun, ini adalah solusi buruk.


3

saya telah menghadapi masalah yang sama. solusi berikut telah bekerja untuk saya.

 FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
        glFrame.addView(yourView);
        glFrame.bringToFront();
        glFrame.invalidate();

Solusi kedua adalah dengan menggunakan xml menambahkan atribut ini ke tampilan xml

android:translationZ=""

2

Anda dapat menggunakan BindingAdapter seperti ini:

@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
    if (flag) {
        view.bringToFront();
    }
}


  <ImageView
        ...
        app:bringToFront="@{true}"/>

0

Anda perlu menggunakan framelayout. Dan cara yang lebih baik untuk melakukan ini adalah membuat tampilan tidak terlihat ketika tidak diperlukan. Anda juga perlu mengatur posisi untuk setiap tampilan, sehingga mereka akan bergerak sesuai dengan posisi yang sesuai di sana


0

Jika Anda menggunakan, LinearLayoutAnda harus menelepon myView.bringToFront()dan setelah Anda menelepon parentView.requestLayout()dan parentView.invalidate()memaksa orang tua untuk menggambar ulang dengan pesanan anak baru.


0

Coba gunakan elevasi di atasnya, sesuatu seperti yourview.setElevation(5);


0

Berkat pengguna Stack atas penjelasan ini , saya dapat menggunakannya bahkan di Android 4.1.1

((View)myView.getParent()).requestLayout();
myView.bringToFront();

Pada penggunaan dinamis saya, misalnya, saya lakukan

public void onMyClick(View v)
     {
     ((View)v.getParent()).requestLayout();
     v.bringToFront();
     }

Dan Bamm!


-2

Atur mereka sesuai urutan yang ingin Anda tampilkan. Misalkan, Anda ingin menampilkan tampilan 1 di atas tampilan 2. Kemudian tulis kode tampilan 2 lalu tulis kode tampilan 1. Jika Anda tidak dapat melakukan pemesanan ini, maka panggil bringToFront () ke tampilan akar tata letak yang ingin Anda bawa di depan.


-32

Anda dapat mengatur visibilitas ke false tampilan lain.

view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...

atau

view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...

dan mengatur

viewN.setVisibility(View.VISIBLE);

4
Saya ingin semua terlihat, itu bukan masalahnya, masalahnya adalah z-order. jika viabilitas adalah masalahnya, itu akan mudah dipecahkan. . .
Lukap
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.