Saya mencoba membuat fungsi kerangka umum yang membuat semua Drawable menjadi disorot saat ditekan / difokuskan / dipilih / dll .
Fungsi saya mengambil Drawable dan mengembalikan StateListDrawable, di mana status defaultnya adalah Drawable itu sendiri, dan status untuk android.R.attr.state_pressed
drawable yang sama, hanya dengan filter yang diterapkan menggunakan setColorFilter
.
Masalah saya adalah saya tidak dapat mengkloning drawable dan membuat instance terpisah dengan filter yang diterapkan. Inilah yang saya coba capai:
StateListDrawable makeHighlightable(Drawable drawable)
{
StateListDrawable res = new StateListDrawable();
Drawable clone = drawable.clone(); // how do I do this??
clone.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
res.addState(new int[] {android.R.attr.state_pressed}, clone);
res.addState(new int[] { }, drawable);
return res;
}
Jika saya tidak mengkloning, maka filter diterapkan secara jelas ke kedua status. Saya mencoba bermain dengan mutate()
tetapi tidak membantu ..
Ada ide?
Memperbarui:
Jawaban yang diterima memang mengkloning drawable. Itu tidak membantu saya karena fungsi umum saya gagal pada masalah yang berbeda. Tampaknya saat Anda menambahkan drawable ke StateList, semua filternya akan hilang.
sumber
ImageView.setImageDrawable
, yang bisa saya atasi berkat jawaban yang diterima.Jawaban:
Coba yang berikut ini:
Drawable clone = drawable.getConstantState().newDrawable();
sumber
.mutate()
(lihat jawaban saya).Jika Anda menerapkan filter / etc ke drawable yang dibuat dengan
getConstantState().newDrawable()
semua instance drawable tersebut akan diubah juga, karena drawable menggunakanconstantState
sebagai cache!Jadi jika Anda mewarnai lingkaran menggunakan filter warna dan a
newDrawable()
, Anda akan mengubah warna semua lingkaran.Jika Anda ingin membuat drawable ini dapat diperbarui tanpa memengaruhi instance lain, Anda harus mengubah status konstanta yang ada itu.
// To make a drawable use a separate constant state drawable.mutate()
Untuk penjelasan yang bagus lihat:
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()
sumber
Inilah yang berhasil untuk saya.
Drawable clone = drawable.getConstantState().newDrawable().mutate();
sumber
Ini adalah solusi saya, berdasarkan pertanyaan SO ini .
Idenya adalah
ImageView
mendapatkan filter warna saat pengguna menyentuhnya, dan filter warna dihapus saat pengguna berhenti menyentuhnya. Hanya 1 drawable / bitmap yang ada di memori, jadi tidak perlu menyia-nyiakannya. Ini bekerja sebagaimana mestinya.class PressedEffectStateListDrawable extends StateListDrawable { private int selectionColor; public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) { super(); this.selectionColor = selectionColor; addState(new int[] { android.R.attr.state_pressed }, drawable); addState(new int[] {}, drawable); } @Override protected boolean onStateChange(int[] states) { boolean isStatePressedInArray = false; for (int state : states) { if (state == android.R.attr.state_pressed) { isStatePressedInArray = true; } } if (isStatePressedInArray) { super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY); } else { super.clearColorFilter(); } return super.onStateChange(states); } @Override public boolean isStateful() { return true; } }
pemakaian:
Drawable drawable = new FastBitmapDrawable(bm); imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
sumber
Saya menjawab pertanyaan terkait di sini
Pada dasarnya, sepertinya StateListDrawables memang kehilangan filternya. Saya membuat BitmapDrawale baru dari salinan Bitmap yang telah diubah yang awalnya ingin saya gunakan.
sumber
dalam kasus
getConstantState()
pengembaliannull
.sumber
Dapatkan clone drawable menggunakan
newDrawable()
tetapi pastikan itu bisa berubah jika tidak efek klon Anda hilang, saya menggunakan beberapa baris kode ini dan berfungsi seperti yang diharapkan.getConstantState()
mungkin null seperti yang disarankan oleh anotasi, jadi tangani RunTimeException ini saat Anda menggandakan drawable.Drawable.ConstantState state = d.mutate().getConstantState(); if (state != null) { Drawable drawable = state.newDrawable().mutate(); }
sumber