Estoy tratando de hacer una función marco general que hace que cualquier Disponibles se resaltarán cuando se pulsa / centrado / seleccionado / etc .
Mi función toma Drawable y devuelve StateListDrawable, donde el estado predeterminado es Drawable en sí mismo, y el estado para android.R.attr.state_pressed
es el mismo dibujable, solo que con un filtro aplicado usando setColorFilter
.
Mi problema es que no puedo clonar el dibujable y hacer una instancia separada con el filtro aplicado. Esto es lo que estoy tratando de lograr:
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;
}
Si no clono, obviamente el filtro se aplica a ambos estados. Intenté jugar con mutate()
pero no ayuda.
¿Algunas ideas?
Actualizar:
De hecho, la respuesta aceptada clona un dibujable. Sin embargo, no me ayudó porque mi función general falla en un problema diferente. Parece que cuando agrega un elemento de diseño a StateList, pierde todos sus filtros.
fuente
ImageView.setImageDrawable
, que pude evitar gracias a la respuesta aceptada.Respuestas:
Intente lo siguiente:
fuente
.mutate()
(mira mi respuesta).Si aplica un filtro / etc a un elemento de diseño creado con
getConstantState().newDrawable()
, todas las instancias de ese elemento de diseño también se cambiarán, ya que los elementos de diseño utilizan elconstantState
como caché!Entonces, si coloreas un círculo con un filtro de color y un
newDrawable()
, cambiarás el color de todos los círculos.Si desea que este elemento de diseño sea actualizable sin afectar a otras instancias, entonces debe mutar ese estado constante existente.
Para obtener una buena explicación, consulte:
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()
fuente
Esto es lo que me funciona.
fuente
Esta es mi solución, basada en esta pregunta SO .
La idea es que
ImageView
obtenga un filtro de color cuando el usuario lo toque, y el filtro de color se elimine cuando el usuario deja de tocarlo. Solo hay 1 mapa de bits / dibujable en la memoria, por lo que no es necesario desperdiciarlo. Funciona como deberia.uso:
fuente
Respondí una pregunta relacionada aquí
Básicamente, parece que StateListDrawables pierde sus filtros. Creé un nuevo BitmapDrawale a partir de una copia alterada del Bitmap que originalmente quería usar.
fuente
en caso de
getConstantState()
devolucionesnull
.fuente
Obtenga clon dibujable usando
newDrawable()
pero asegúrese de que sea mutable, de lo contrario su efecto de clonación desaparecerá, utilicé estas pocas líneas de código y está funcionando como se esperaba.getConstantState()
puede ser nulo como lo sugiere la anotación, así que maneje esta RunTimeException mientras clona el elemento de dibujo.fuente