Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


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:

  • Cómo obtener la ruta correcta después de cortar la imagen?
  • Android - proveedor de archivos - permiso de denegación
  • Cómo configurar Height Width de ImageView de forma programática en android?
  • Creación de un android.graphics.Bitmap desde C ++
  • Cómo vaciar (borrar) el búfer logcat en Android
  • ¿Cuál es la unidad predeterminada de estilo en React Native?
    • 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?

  • Cómo extraer el código del archivo apk
  • ¿Puedo seguir recibiendo la intención del receptor de difusión después de que la fuerza detuviera mi aplicación en android?
  • ¿Cómo puedo enviar JSon como BODY en una solicitud POST al servidor desde una aplicación de Android?
  • ¿Debe ser una clase DialogFragment interna estática o no?
  • Android 4.3 Perfil de GPU en pantalla - tiempo de espera de gfx largo
  • Android y ActionBarCompat: cómo cambiar la visibilidad de las acciones en tiempo de ejecución en dispositivos pre-ICS?
  • 6 Solutions collect form web for “SetColorFilter () roto en Android 4, trabajando en Android 5”

    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.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.