Saya ingin memiliki 2 tema yang dapat dipilih untuk aplikasi saya. Untuk melakukan itu, saya mendefinisikan beberapa atribut, seperti ini:
<attr format="color" name="item_background" />
Kemudian, saya membuat kedua tema tersebut, seperti ini:
<style name="ThemeA">
<item name="item_background">#123456</item>
</style>
<style name="ThemeB">
<item name="item_background">#ABCDEF</item>
</style>
Metode ini berfungsi dengan baik, memungkinkan saya membuat dan memodifikasi beberapa tema dengan mudah. Masalahnya adalah sepertinya itu hanya bisa digunakan di Views, dan bukan di Drawables .
Misalnya, mereferensikan nilai dari View di dalam layout berfungsi:
<TextView android:background="?item_background" />
Tetapi melakukan hal yang sama di Drawable tidak:
<shape android:shape="rectangle">
<solid android:color="?item_background" />
</shape>
Saya mendapatkan kesalahan ini saat menjalankan aplikasi:
java.lang.UnsupportedOperationException: Can't convert to color: type=0x2
Jika alih-alih ?item_background
saya menggunakan warna hardcode, itu berfungsi, tetapi itu tidak memungkinkan saya untuk menggunakan tema saya. Saya juga mencoba ?attr:item_background
, tetapi hal yang sama terjadi.
Bagaimana saya bisa melakukan ini? Dan mengapa ini berfungsi di Views, tetapi tidak di Drawables? Saya tidak dapat menemukan batasan ini di mana pun dalam dokumentasi ...
Jawaban:
Menurut pengalaman saya, tidak mungkin mereferensikan atribut dalam drawable XML.
Untuk membuat tema Anda, Anda perlu:
Sertakan warna yang dibutuhkan ke dalam drawable Anda secara langsung dengan
@color
tag atau format #RGB.Buat atribut untuk drawable Anda di attrs.xml .
Tambahkan drawable Anda ke theme.xml .
Referensi drawable Anda dalam tata letak menggunakan atribut Anda.
sumber
Dimulai dengan
lollipop
(API 21) fitur ini didukung, lihat https://code.google.com/p/android/issues/detail?id=26251Namun, jika Anda menargetkan perangkat tanpa lollipop, jangan gunakan, karena akan mogok, gunakan solusi di jawaban yang diterima.
sumber
Meskipun tidak mungkin untuk mereferensikan atribut gaya dari drawable pada perangkat pra-Lollipop , tetapi mungkin untuk daftar status warna. Anda bisa menggunakan metode AppCompatResources.getColorStateList (Context context, int resId) dari Android Support Library. Sisi negatifnya adalah Anda harus mengatur daftar status warna tersebut secara terprogram.
Ini adalah contoh yang sangat mendasar.
color / my_color_state.xml
Widget yang membutuhkan daftar status warna:
Dan yang terpenting:
Yah, bukan cara yang paling elegan atau terpendek, tetapi inilah yang dilakukan oleh Perpustakaan Dukungan Android untuk membuatnya berfungsi pada versi Android yang lebih lama (pra-Lollipop).
Sayangnya, metode serupa untuk drawable tidak berfungsi dengan atribut gaya.
sumber
Saya menjawab pertanyaan yang sama di https://stackoverflow.com/a/59467269/3841352 tetapi saya akan mempostingnya di sini juga:
Saya mengalami masalah yang sama dan pada 2019 belum terselesaikan sehingga Anda tidak dapat memiliki atribut yang direferensikan di pemilih sebagai drawable. Saya akan membagikan solusi yang saya dapatkan untuk masalah ini karena saya tidak melihatnya diposting di sini. Saya menemukannya di komentar terakhir dari laporan bug .
Solusinya pada dasarnya adalah membuat sumber daya yang dapat digambar yang akan merujuk pada nilai atribut.
Untuk mengilustrasikan kasus Anda, solusinya adalah:
Anda akan mengganti? attr / * untuk sumber daya yang dapat digambar:
Drawable akan didefinisikan sebagai:
drawable / colorPrimaryDrawable
drawable / colorPrimaryDarkDrawable
Semoga membantu !!
sumber
Seperti yang dikatakan @marmor, ini sekarang didukung pada API 21. Tetapi bagi kami yang membutuhkan dukungan versi lama Android, Anda dapat menggunakan fitur ini. Menggunakan pustaka dukungan v7, Anda masih dapat menggunakannya di aplikasi dengan level SDK minimum hingga 7.
The
AppCompatImageView
di v7 Dukungan Perpustakaan Android memiliki implementasi bebas bug dari fitur ini. Cukup ganti penggunaan AndaImageView
denganAppCompatImageView
.sumber