Estoy tratando de tinte de una imagen antes de Android API de nivel 21. He éxito teñida de elementos mediante:

<android:tint="@color/red"/>

Sin embargo, me parece que no puede averiguar cómo hacerlo a través de código en un ImageView:

Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);

He probado la configuración de la TintMode pero esto parece que no hacen diferentes. Estoy usando la v4 de compatibilidad de clase DrawableCompat incorrectamente?

  • Me las arreglé para conseguir el efecto que yo estaba buscando, mediante la aplicación de un ColorFilter, utilizando el modo SRC_IN que creo que significa que sólo se multiplica el canal alfa por el color – que era lo que yo quería con el matiz de todos modos: setColorFilter(este.mContext.getResources().getColor(R. de color.rojo), PorterDuff.Modo.SRC_IN)
InformationsquelleAutor Hippopatimus | 2014-11-06

7 Comentarios

  1. 43

    La forma más sencilla de tinte de la cruz-plataforma (si usted no necesita un ColorStateList) es:

    drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);

    No te olvides de mutar la Imagen antes de aplicar el filtro.

    • No sé por qué alguien votada abajo de este, pero este código es en realidad lo que AppCompat hace bajo la capucha para las anteriores versiones de Android. El AppCompat de la API es bastante detallado para hacer esto así que no creo que haya mucho que ganar mediante el uso de ella en comparación con este código.
    • DrawableComapat.setTint(_, _) tenido algún problema mientras yo trataba de llevar a cabo varias veces en prelollipop. Y tengo esto como una solución. Gracias
  2. 120

    En caso de que alguien necesita usar DrawableCompat‘s tintado sin afectar a otros dibujables, aquí te explicamos cómo hacerlo con mutate():

    Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
    Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
    wrappedDrawable = wrappedDrawable.mutate();
    DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.white));

    Que se puede simplificar a:

    Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
    drawable = DrawableCompat.wrap(drawable);
    DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));
    • mutar() es la forma correcta de hacerlo. Sin ella, estás tiñendo el dibujable globalmente para toda la aplicación. Para citar el javadoc: «mutables dibujable está garantizado para no compartir su estado con cualquier otra imagen. Esto es especialmente útil cuando se necesita para modificar las propiedades de los dibujables cargado de recursos. De forma predeterminada, todos los dibujables las instancias de carga desde el mismo recurso compartido de un estado común; si se modifica el estado de una instancia, todas las demás instancias de recibir la misma modificación.»
    • No funciona con Android 4.1.X y a continuación
    • Esto funciona en la API de 19 y API 23, pero no en la API de 21.
    • Funciona bien para 4.1 y superior (API de 16 y más). Probado con la última de la biblioteca de soporte (23.1.1). La mutar es necesario en 4.1 por lo menos. Obras en 21 y 23.
    • Si usted necesita usar un selector, el uso de DrawableCompat.setTintList() lugar.
    • si utiliza este método, dibujable matiz es cambiado de forma global, sin volver. Uno de lib yo uso, utiliza este código, y cambia mi dibujable del color de forma global en todas las actividades que @Brett estás equivocado
    • getResources().getColor(int res) – está en desuso, para conseguir un color con sólo un Contexto de uso ContextCompat.getColor(context, R.color.my_color);

  3. 53

    Previamente teñido no fue apoyada por DrawableCompat.
    A partir de la biblioteca de soporte 22.1 usted puede hacer eso, pero es necesario hacerlo de esta forma:

    Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
    Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
    DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
    • Me pregunto si alguien puede conseguir este trabajo con mutate() dibujable
    • Estoy bastante seguro de que no la necesito, pero me acaba de publicar una respuesta aquí, por medio de DrawableCompat‘s teñido con mutate(). Pensé que te gustaría echarle un vistazo de todos modos 🙂
    • No funciona con Android 4.1.X y a continuación
    • Esto funciona en la API de nivel 23 y nivel de API 19, pero no en la API de nivel 21.
    • He tenido que añadir una imagen.invalidateSelf() para que funcione, pero aparte de eso, no hay problemas
  4. 29

    Las respuestas aquí no están trabajando para pre-lollipop-dispositivos (SupportLib 23.4.0) pero he publicado una solución que trabaja por la API de 17: https://stackoverflow.com/a/37434219/2170109

    El siguiente código ha sido probado y se está trabajando en la Api 17, 19, 21, 22, 23 y N vista previa de 3:

        //https://stackoverflow.com/a/30928051/2170109
        Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
        image.setImageDrawable(drawable);
    
        /*
         * need to use the filter | https://stackoverflow.com/a/30880522/2170109
         * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
         */
        int color = ContextCompat.getColor(context, R.color.yourcolor);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            DrawableCompat.setTint(drawable, color);
    
        } else {
            drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
        }
    • No puedo creer que nadie votó esta arriba
    • No DrawableCompat ya realizar esta comprobación para nosotros? De ahí el nombre de «Compat…». La documentación de la clase: /** * Ayudante para acceder a funciones en {@link de android.gráficos.dibujable.Dibujable} * se introdujo después de la API de nivel 4 en un compatible de la moda. */
    • como dije en mi otro post (stackoverflow.com/a/37434219/2170109) tenía problemas para conseguir que funcione en todas las Api – incluso como el Compat-clase afirma ser la única solución.
  5. 6

    Si miramos el código fuente de DrawableCompat usted verá que para cualquier versión de < 21 el método no hace nada.

    La idea de DrawableCompat parece ser, simplemente, de no estrellarse en versiones antiguas, en lugar de proporcionar esa funcionalidad.

    • Esta es una enorme limitación de la DrawableCompat enfoque y parece llevar a cabo para la aplicación de compat versiones > 22.1.
    • Si usted realmente seguir la clase que se utiliza verás que DrawableWrapper implementa tinte con un filtro de color.
    • la pregunta sigue siendo, puedes publicar de cómo hacerlo correctamente, ninguna de las respuestas en este post funciona completamente, o que son demasiado vagos.
  6. 3

    Con el apoyo de la biblioteca 22.1 puede utilizar DrawableCompat para teñir dibujables.

    DrawableCompat.wrap(Dibujable) y setTint(), setTintList(), y setTintMode() se acaba de trabajar: no hay necesidad de crear y mantener separados los dibujables sólo para el soporte de múltiples colores!

    • No funciona con Android 4.1.X y a continuación
  7. 2

    Voy a compartir mi solución aquí porque se puede ahorrar un poco de tiempo a alguien.

    Tuve una ImageView con vector de la imagen se utiliza como fuente de dibujable (en realidad, fue de Vectores de Soporte Dibujable de Android Support Library 23.3). Así, en primer lugar he envuelto así:

    mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));

    Y después de que intenté aplicar el tinte es así:

    DrawableCompat.setTint(
        mImageView.getDrawable(),
        getResources().getColor(R.color.main_color)
    );

    Sin suerte.

    Traté de llamar mutate() envuelto en dibujable, así como en la original dibujable – aún sin suerte. invalidate() llamado en mImageView hizo el truco.

    • Tu no usas AppCompatImageView?

Dejar respuesta

Please enter your comment!
Please enter your name here