android - programa - quitar filtros de fotos online
Android: clonando un dibujable para hacer un StateListDrawable con filtros (5)
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 elimina cuando el usuario deja de tocarlo. Solo 1 drawable / bitmap está en la memoria, por lo que no hay necesidad de desperdiciarlo. Funciona como deberia.
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;
}
}
uso:
Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
Intento crear una función de marco general que haga resaltar cualquier Drawable cuando se presiona / enfoca / selecciona / etc.
Mi función toma un Drawable y devuelve un StateListDrawable, donde el estado predeterminado es Drawable, y el estado de android.R.attr.state_pressed
es el mismo dibujable, solo con un filtro aplicado usando setColorFilter
.
Mi problema es que no puedo clonar el dibujable y crear 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 lo hago, entonces el filtro obviamente se aplica a ambos estados. Intenté jugar con mutate()
pero no ayuda ...
¿Algunas ideas?
Actualizar:
La respuesta aceptada en verdad clona un dibujable. Aunque no me ayudó porque mi función general falla en un problema diferente. Parece que cuando agrega un drawable a StateList, pierde todos sus filtros.
Esto es lo que funciona para mí.
Drawable clone = drawable.getConstantState().newDrawable().mutate();
Pruebe lo siguiente:
Drawable clone = drawable.getConstantState().newDrawable();
Respondí una pregunta relacionada here
Básicamente, parece que StateListDrawables pierde sus filtros. Creé un nuevo BitmapDrawale a partir de una copia alterada del mapa de bits que originalmente quería usar.
Si aplicas un filtro / etc a un getConstantState().newDrawable()
creado con getConstantState().newDrawable()
, todas las instancias de ese dibujable también se cambiarán, ¡ya que los dibujables usan constantState
como caché!
Por lo tanto, si coloreas un círculo con un filtro de color y nuevoDrawable, cambiarás el color de todos los círculos.
Si desea hacer que este dibujable sea actualizable sin afectar otras instancias, entonces debe mutar ese estado constante existente.
// To make a drawable use a separate constant state
drawable.mutate()
Para una buena explicación, ver:
http://www.curious-creature.org/2009/05/02/drawable-mutations/
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate()