SetColorFilter () roto en Android 4, trabajando en Android 5
Estoy intentando destellar diversos colores en la pantalla en los intervalos regulares (algunas veces por segundo).
Para cambiar los colores, utilizo Drawable.setColorFilter(int color, Mode mode)
en el fondo de mi vista principal:
- Cambios de color de fondo de Android con ViewPager en ICS
- AlphaAnimation no funciona en Sandwich de helado
- Cálculo del tamaño de Appwidget
- El emulador acelerado de Android sigue reiniciando
- Buscando la configuración correcta de AVD para emular un Samsung Galaxy Nexus (usando android-4.x, ICS)
-
myView.getBackground().setColorFilter(Color.RED, PorterDuff.Mode.SRC);
Para propósitos de depuración, agregué otra vista que cambio con View.setBackgroundColor(int color)
.
El problema es que las llamadas setColorFilter()
están funcionando en Lollipop , pero están rotas en versiones anteriores (específicamente Nexus 7 v4.4.4, Galaxy Nexus v4.2.1).
Llamo el código que cambia de color dentro de un Runnable
que es disparado a intervalos regulares por un Handler
.
El manejador se llama en todas las plataformas (puedo ver los cambios de fondo debido a las llamadas setBackgroundColor()
depuración).
A continuación se muestra el código de color:
Handler mHandler; RunnableOnTick thisRunnable; View vDebug; View vBroken; class RunnableOnTick implements Runnable { int backgroundColor; @Override public void run() { color = random.nextInt(2); switch (color) { case 0: { backgroundColor = Color.RED; break; } case 1: { backgroundColor = Color.GREEN; break; } } // this works on all platforms vDebug.setBackgroundColor(backgroundColor); // this works only on Lollipop vBroken.getBackground().setColorFilter(backgroundColor, PorterDuff.Mode.SRC); vBroken.invalidate(); mHandler.postDelayed(thisRunnable, 100); } }
He intentado diferentes valores de PorterDuff.Mode
– todavía no puedo conseguir que funcione en Android 4.
¿Qué es diferente entre Android v4 y v5 que cambiaría la forma en que setColorFilter()
funciona?
- Videos que no se reproducen en modo de pantalla completa
- Aplicación segura para bebés en android
- HttpURLConnection realiza siempre una solicitud GET en lugar de una solicitud POST a pesar de setDoOutput (true) y setRequestMethod ("POST")
- Cómo detectar los clics de botón del sistema "Aplicaciones recientes" (Honeycomb +)
- Cómo utilizar el widget de NumberPicker Android 4.0
- XmlPullParserException sólo en ICS
- Crea un duplicado de un campo de entrada cuando se enfoca en android 4.0 webview usando jquery móvil y phonegap
- No se puede mostrar el teclado automáticamente en el SearchView
En última instancia, parece que el problema es que KitKat no admite el uso de un ColorFilter (o implícitamente un alfa) en un Drawable que a su vez estará en un StateListDrawable. Mi solución fue usar el mismo código para construir el complejo Drawable y luego convertirlo en un simple BitMapDrawable:
static Drawable createDrawable(Context context, int color, boolean disabled) { OvalShape oShape = new OvalShape(); ShapeDrawable background = new ShapeDrawable(oShape); background.getPaint().setColor(color); ShapeDrawable shader = new ShapeDrawable(oShape); shader.setShaderFactory(new ShapeDrawable.ShaderFactory() { @Override public Shader resize(int width, int height) { return new LinearGradient(0, 0, 0, height, new int[]{ Color.WHITE, Color.GRAY, Color.DKGRAY, Color.BLACK }, null, Shader.TileMode.REPEAT); } }); Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_chat_button).mutate(); icon.setColorFilter(context.getResources().getColor(R.color.control_tint_color), PorterDuff.Mode.SRC_IN); Drawable layer = new LayerDrawable(new Drawable[]{ shader, background, icon }); layer.setAlpha(disabled ? 128 : 255); // Note that on KitKat, setting a ColorFilter on a Drawable contained in a StateListDrawable // apparently doesn't work, although it does on later versions, so we have to render the colored // bitmap into a BitmapDrawable and then put that into the StateListDrawable Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); layer.setBounds(0, 0, layer.getIntrinsicWidth(), layer.getIntrinsicHeight()); layer.draw(canvas); return new BitmapDrawable(context.getResources(), bitmap); }
Hay un problema en AppCompat con el compuesto Drawable
debajo de API 21 que me parece que está relacionado: https://code.google.com/p/android/issues/detail?id=191111
La solución simple no es usar drawables de XML pero crearlos en código y luego aplicar setColorFilter
. Es por eso que la solución @Hardeep funcionó.
Fun trivia: En mi caso setColorFilter
en XML creado TextView
funcionó bien, pero sólo cuando se invocó a través del controlador de clics / retrasado. Cuando se invocó en onCreate
/ onResume
etc no sucedió nada.
Para mí, un ColorFilter no se aplicaría a un elemento de color en un StateListDrawable.
Crear un Drawable para representar ese color y usarlo en su lugar en StateListDrawable vi setColorFilter trabajando en dispositivos pre-Lollipop que probé.
Como una nota lateral, hice un dibujo blanco puro de modo que el color que tiñe se aplicara en la opacidad completa.
¿Has intentado directamente de esta manera ?!
vBroken.getBackground().setColorFilter(Color.argb(255, 255, 255, 255),PorterDuff.Mode.MULTIPLY));
Tuve el mismo problema en pre-lollipop, resolví reemplazar:
vBroken.getBackground().setColorFilter(backgroundColor, PorterDuff.Mode.SRC);
con:
Drawable d = vBroken.getBackground(); d.setColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY); vBroken.setBackground(d);
/** * Tint / Colorise the Supplied {@code drawable} into another color of supplied {@code colorResId} * @param context * @param drawable * @param colorResId * @return */ public Drawable tintThisDrawable(Context context ,Drawable drawable,@ColorRes int colorResId) { Resources res = context.getResources(); int color = res.getColor(colorResId); if (drawable != null) { drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); } return drawable; }
Recuerdo que esta función funciona en algún lugar de mi proyecto. Prueba por ti mismo.
- Cómo cambiar el tamaño del marcador de imagen de ImageView con picasso
- ¿Cuánto tiempo debe tardar en registrarse como desarrollador de Google Play?