Bagaimana cara mengatur efek klik tombol di Android?


105

Di Android, saat saya menyetel gambar latar belakang ke Tombol, saya tidak bisa melihat efek apa pun pada tombol.

Saya membutuhkan beberapa efek pada tombol sehingga pengguna dapat mengenali tombol yang diklik.

Tombol harus gelap selama beberapa detik saat diklik, jadi apa yang harus saya lakukan untuk ini?

Terima kasih.



Metode berikut memungkinkan Anda menggunakan satu styleclass untuk menguliti semua tombol Anda, apa pun teksnya: stackoverflow.com/questions/5327553/…
Zack Marrapese

tidak Saya tidak menggunakan Tombol Gambar, apakah saya menggunakan Tombol Normal dengan cara yang mudah untuk ini?
Jignesh Ansodariya

Jawaban:


154

Ini dapat dicapai dengan membuat file xml drawable yang berisi daftar status untuk tombol tersebut. Jadi misalnya jika Anda membuat file xml baru bernama "button.xml" dengan kode berikut:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/YOURIMAGE" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:drawable="@drawable/YOURIMAGE" />
</selector>

Untuk menyimpan gambar latar belakang dengan tampilan yang digelapkan saat dicetak, buat file xml kedua dan beri nama gradient.xml dengan kode berikut:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <bitmap android:src="@drawable/YOURIMAGE"/>
    </item>
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <gradient android:angle="90" android:startColor="#880f0f10" android:centerColor="#880d0d0f" android:endColor="#885d5d5e"/>
        </shape>
    </item>
</layer-list>

Dalam xml tombol Anda atur latar belakang menjadi tombol xml misalnya

android:background="@drawable/button"

Semoga ini membantu!

Edit: Mengubah kode di atas untuk menampilkan gambar (GAMBAR ANDA) di tombol sebagai lawan dari warna blok.


Lalu di mana saya dapat mengatur Gambar untuk Latar Belakang Tombol, untuk mengatur Gambar adalah harus
Jignesh Ansodariya

1
Diedit untuk menunjukkan cara menggunakan gambar latar belakang dengan status XML. Ganti GAMBAR ANDA dengan sumber daya gambar di direktori drawable Anda.
Ljdawson

Ini hanya berfungsi jika src dari tombol berbentuk persegi panjang. Jika src drawable memiliki bentuk yang berbeda dari itu, gradien akan diterapkan ke latar belakang juga, dan ini menyedihkan.
Renato Lochetti

Tidak juga, selalu bisa menggunakan bentuk yang berbeda dalam daftar lapisan
Ljdawson

2
sementara saya menggunakan gambar, itu berfungsi untuk saya .. tetapi ketika saya menggunakan latar belakang Xml. tidak bekerja ...
DKV

88

Ini lebih sederhana ketika Anda memiliki banyak tombol gambar, dan Anda tidak ingin menulis xml-s untuk setiap tombol.

Versi Kotlin:

fun buttonEffect(button: View) {
    button.setOnTouchListener { v, event ->
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                v.background.setColorFilter(-0x1f0b8adf, PorterDuff.Mode.SRC_ATOP)
                v.invalidate()
            }
            MotionEvent.ACTION_UP -> {
                v.background.clearColorFilter()
                v.invalidate()
            }
        }
        false
    }
}

Versi Java:

public static void buttonEffect(View button){
    button.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.getBackground().clearColorFilter();
                    v.invalidate();
                    break;
                }
            }
            return false;
        }
    });
}

2
Saya menggunakan ini dalam kode saya dan satu-satunya masalah yang saya perhatikan sejauh ini adalah tombol berperilaku aneh ketika ditempatkan di ScrollView.
Finnboy11

Ini benar-benar solusi yang luar biasa dan ini harus menjadi jawaban yang benar
Biraj Zalavadia

Bagaimana ini lebih baik? Mendesain harus disimpan di luar kode, bukan?
Bug Terjadi

Ini hanya solusi sederhana untuk masalah ini. Bila Anda memiliki banyak tombol dan Anda tidak ingin membuat xml untuk setiap tombol, ini bisa membantu.
András

Oh Tuhan! Bayangkan memiliki 5 tombol dalam sebuah fragmen ... Anda akan memiliki sejumlah besar kode boilerplate ini ... Lalu bagaimana cara merefaktornya? Ubah filter warna untuk semua tombol di semua aktivitas? Imho, pengembang Anda berikutnya tidak akan begitu senang ..
Leo Droidcoder

84

Buat AlphaAnimationObjek Anda yang menentukan seberapa banyak efek memudar dari tombol, lalu biarkan mulai dionClickListener dari tombol Anda

Sebagai contoh :

private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);

// some code

public void onClick(View v) {
    v.startAnimation(buttonClick);
}

tentu saja ini hanya cara, bukan yang paling disukai, hanya lebih mudah


5
Yang saya suka tentang solusi ini, adalah tidak memerlukan banyak pemilih untuk dibuat, ketika Anda memiliki banyak tombol dengan gambar kustomnya masing-masing.
Pete

2
Ini tidak memudarkan tombol pada satu sentuhan, itu hanya memudarkannya selama sepersekian detik setelah klik terdeteksi dan jari pengguna telah terangkat.
Doug Voss

1
Bagus dan sederhana

@Doug Voss, Anda dapat mengatur durasi animasi menjadi lebih lama
Ahmed Adel Ismail

bagaimana dengan onLongClick dan 'circularReveal'?
Acauã Pitta

44

Anda cukup menggunakan latar depan untuk Viewmendapatkan efek yang dapat diklik:

android:foreground="?android:attr/selectableItemBackground"


Untuk digunakan dengan tema gelap, tambahkan juga tema ke Anda layout(agar efek yang dapat diklik menjadi jelas):

android:theme="@android:style/ThemeOverlay.Material.Dark"

5
Cara termudah untuk menerapkan. Untuk diketahui, Atribut android: latar depan tidak berpengaruh pada level API yang lebih rendah dari 23.
dolgom

1
Solusi paling sederhana.
Jerry Chong

2
Ini harus menjadi jawaban yang diterima, jauh lebih sederhana dan menambahkan efek animasi riak yang bagus.
Tyler

1
@dolgom Untuk API level <23 gunakanlah pada atribut "background". Jadi: android: background = "? android: attr / selectableItemBackground"
Z3R0

24

Untuk membuat item Anda konsisten dengan tampilan dan nuansa sistem, coba referensi atribut sistem android:attr/selectableItemBackgrounddi tag latar depan atau latar depan tampilan yang Anda inginkan:

<ImageView
    ...
    android:background="?android:attr/selectableItemBackground"      
    android:foreground="?android:attr/selectableItemBackground"
    ...
/>

Gunakan kedua atribut untuk mendapatkan efek yang diinginkan sebelum / sesudah API level 23 masing-masing.

https://stackoverflow.com/a/11513474/4683601


2
Sejauh ini solusi paling sederhana. Terima kasih!
tykom

9

Atau hanya dengan menggunakan satu gambar latar belakang Anda dapat memperoleh efek klik dengan menggunakan setOnTouchListener

Dua arah

((Button)findViewById(R.id.testBth)).setOnTouchListener(new OnTouchListener() {

      @Override
        public boolean onTouch(View v, MotionEvent event) {
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN: {
                  Button view = (Button) v;
                  view.getBackground().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
                  v.invalidate();
                  break;
              }
              case MotionEvent.ACTION_UP:
                  // Your action here on button click
              case MotionEvent.ACTION_CANCEL: {
                  Button view = (Button) v;
                  view.getBackground().clearColorFilter();
                  view.invalidate();
                  break;
              }
          }
          return true;
        }
});

masukkan deskripsi gambar di sini

Dan jika Anda tidak ingin menggunakan setOnTouchLister, cara lain untuk mencapainya adalah

    myButton.getBackground().setColorFilter(.setColorFilter(0xF00, Mode.MULTIPLY);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {android.R.attr.defaultValue}, myButton);

    myButton.setBackgroundDrawable(listDrawable);

ada kesalahan dalam kode dengan cara ke-2. Apa itu fungsi getCurrent ()? Juga myButton bukan Drawable sehingga tidak bisa ditambahkan sebagai status.
Ehtesham Hasan

Terima kasih telah menunjukkan kesalahannya. Saya telah memperbaikinya, dan myButton adalah turunan dari kelas Tombol yang menyediakan metode setBackgroundDrawable dan mengambil contoh Drawable, maka ini akan berhasil.
Vinayak Bevinakatti

Lihat jawaban saya yang didasarkan pada pendekatan kedua Anda. stackoverflow.com/a/39430738/5229515
Ehtesham Hasan

Ini mungkin harus memiliki "return false" di akhir sehingga tidak mengkonsumsi acara dan onClickListeners tambahan apa pun dapat dipanggil.
Doug Voss

3

hanya ingin menambahkan cara lain yang mudah untuk melakukan ini: Jika ImageButton Anda tetap menjadi latar belakang dan Anda tidak menyetelnya ke null, ini akan berfungsi seperti tombol normal dan akan menampilkan animasi klik saat mengklik persis seperti tombol lainnya. latar belakang saat masih ada:

<ImageButton
    android:id="@+id/imageButton2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingBottom="1dp"
    android:paddingLeft="1dp"
    android:paddingRight="1dp"
    android:paddingTop="1dp"
    android:src="@drawable/squareicon" />

Paddings tidak akan membiarkan background terlihat dan membuat tombol tersebut berfungsi seperti tombol lainnya.


1
ini akan mempertahankan batas tombol persegi di sekitar gambar jika berbentuk lingkaran
MSaudi

3

Ini adalah solusi terbaik yang saya dapatkan dengan mengambil petunjuk dari jawaban @ Vinayak. Semua solusi lainnya memiliki kekurangan yang berbeda.

Pertama-tama buat fungsi seperti ini.

void addClickEffect(View view)
{
    Drawable drawableNormal = view.getBackground();

    Drawable drawablePressed = view.getBackground().getConstantState().newDrawable();
    drawablePressed.mutate();
    drawablePressed.setColorFilter(Color.argb(50, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {}, drawableNormal);
    view.setBackground(listDrawable);
}

Penjelasan:

getConstantState (). newDrawable () digunakan untuk menggandakan Drawable yang ada, jika tidak, drawable yang sama akan digunakan. Baca lebih lanjut dari sini: Android: Menggandakan drawable untuk membuat StateListDrawable dengan filter

mutate () digunakan untuk membuat klon Drawable tidak membagikan statusnya dengan instance Drawable lainnya. Baca lebih lanjut di sini: https://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()

Pemakaian:

Anda dapat meneruskan semua jenis View (Button, ImageButton, View dll) sebagai parameter ke fungsi dan mereka akan mendapatkan efek klik yang diterapkan padanya.

addClickEffect(myButton);
addClickEffect(myImageButton);

2
Step: set a button in XML with onClick Action:

 <Button
android:id="@+id/btnEditUserInfo"
style="?android:borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/txt_height"
android:layout_gravity="center"
android:background="@drawable/round_btn"
android:contentDescription="@string/image_view"
android:onClick="edit_user_info"
android:text="Edit"
android:textColor="#000"
android:textSize="@dimen/login_textSize" />

Step: on button clicked show animation point
//pgrm mark ---- ---- ----- ---- ---- ----- ---- ---- -----  ---- ---- -----

    public void edit_user_info(View view) {

        // show click effect on button pressed
        final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
        view.startAnimation(buttonClick);

        Intent intent = new Intent(getApplicationContext(),  EditUserInfo.class);
        startActivity(intent);

    }// end edit_user_info

2

Gunakan RippleDrawable untuk efek ditekan / diklik dengan status Desain Material.

Untuk melakukannya, buat item ripple sebagai folder .xml di bawah / drawable dan gunakan di android: background untuk tampilan apa pun.

  • Efek untuk ikon ditekan / diklik, gunakan efek riak melingkar, misalnya:

    <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/darker_gray" />

  • Efek untuk tampilan diklik dengan batas persegi panjang, kita bisa menambahkan riak pada drawable yang ada seperti di bawah ini:

    <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#000000"> <item android:drawable="@drawable/your_background_drawable"/> </ripple>


2

Untuk semua tampilan

android:background="?android:attr/selectableItemBackground"

Tetapi untuk cardview yang memiliki penggunaan elevasi

android:foreground="?android:attr/selectableItemBackground"

Untuk efek klik melingkar seperti pada toolbar

android:background="?android:attr/actionBarItemBackground"

Anda juga perlu mengatur

 android:clickable="true"
 android:focusable="true"

0

Membuat tambahan kecil pada jawaban Andràs:

Anda dapat menggunakan postDelayeduntuk membuat filter warna bertahan selama beberapa waktu agar lebih terlihat:

        @Override
        public boolean onTouch(final View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            v.getBackground().clearColorFilter();
                            v.invalidate();
                        }
                    }, 100L);
                    break;
                }
            }
            return false;
        }

Anda dapat mengubah nilai penundaan 100L sesuai dengan kebutuhan Anda.


0

Jika Anda menggunakan latar belakang xml dan bukan IMG, hapus saja ini:

<item>
    <bitmap android:src="@drawable/YOURIMAGE"/>
</item>

dari jawaban pertama yang diberikan @Ljdawson kepada kami.

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.