Misalnya, tombol default memiliki dependensi berikut antara status dan gambar latar belakangnya:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/btn_default_normal_disable" />
<item android:state_pressed="true"
android:drawable="@drawable/btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/btn_default_normal_disable" />
</selector>
Bagaimana saya bisa mendefinisikan status kustom saya sendiri (seperti apa android:state_custom
), sehingga saya bisa menggunakannya untuk secara dinamis mengubah tampilan visual tombol saya?
Jawaban:
Solusi yang ditunjukkan oleh @ (Ted Hopp) berfungsi, tetapi membutuhkan sedikit koreksi: di pemilih, status item memerlukan awalan "app:", jika tidak, inflater tidak akan mengenali namespace dengan benar, dan akan gagal secara diam-diam; setidaknya inilah yang terjadi pada saya.
Izinkan saya melaporkan di sini seluruh solusi, dengan beberapa perincian lebih lanjut:
Pertama, buat file "res / values / attrs.xml":
Kemudian tentukan kelas khusus Anda. Misalnya, itu mungkin kelas "FoodButton", berasal dari kelas "Tombol". Anda harus mengimplementasikan konstruktor; mengimplementasikan yang ini, yang tampaknya menjadi yang digunakan oleh inflater:
Di atas kelas turunan:
Juga, variabel status Anda:
Dan beberapa setter:
Kemudian timpa fungsi "onCreateDrawableState":
Akhirnya, bagian paling rumit dari teka-teki ini; pemilih mendefinisikan StateListDrawable yang akan Anda gunakan sebagai latar belakang untuk widget Anda. Ini adalah file "res / drawable / food_button.xml":
Perhatikan awalan "app:", sedangkan dengan status android standar Anda akan menggunakan awalan "android:". Namespace XML sangat penting untuk interpretasi yang benar oleh inflater dan tergantung pada jenis proyek di mana Anda menambahkan atribut. Jika itu adalah aplikasi, ganti com.mydomain.mypackage dengan nama paket aplikasi Anda yang sebenarnya (tidak termasuk nama aplikasi). Jika perpustakaan, Anda harus menggunakan "http://schemas.android.com/apk/res-auto" (dan menggunakan Tools R17 atau yang lebih baru) atau Anda akan mendapatkan kesalahan runtime.
Beberapa catatan:
Tampaknya Anda tidak perlu memanggil fungsi "refreshDrawableState", setidaknya solusinya berfungsi dengan baik, dalam kasus saya
Untuk menggunakan kelas khusus Anda dalam file xml tata letak, Anda harus menentukan nama yang sepenuhnya memenuhi syarat (mis. Com.mydomain.mypackage.FoodButton)
Anda dapat sebagai negara campuran standar (mis. Android: ditekan, android: diaktifkan, android: dipilih) dengan status khusus, untuk mewakili kombinasi keadaan yang lebih rumit
sumber
refreshDrawableState
jelas penting. Saya tidak begitu yakin kapan itu benar-benar dibutuhkan. Tetapi dalam kasus saya itu diperlukan ketika mengatur negara secara terprogram. Saya kira itu mungkin dipanggil dari kelas View secara otomatis di onTouchEvent. Saya lebih baik menambahkannya dalam metode setSelected.boolean
? Atau apakah penyeleksi hanya beroperasi pada boolean?Utas ini menunjukkan cara menambahkan status khusus ke tombol dan sejenisnya. (Jika Anda tidak dapat melihat grup Google baru di browser Anda, ada salinan utas di sini .)
sumber
Tolong jangan lupa untuk menelepon di
refreshDrawableState
dalam utas UI:Butuh banyak waktu saya untuk mencari tahu mengapa tombol saya tidak mengubah kondisinya meskipun semuanya terlihat benar.
sumber