¿Cómo configurar el tinte para una vista de imagen mediante programación en Android?

397

Necesito configurar el tinte para una vista de imagen ... Lo estoy usando de la siguiente manera:

imageView.setColorFilter(R.color.blue,android.graphics.PorterDuff.Mode.MULTIPLY);

Pero no cambia ...

Alexander Farber
fuente
15
Es posible que haya utilizado la identificación del recurso entero en lugar del valor de color entero, intente convertir R.color.blue en getResources (). GetColor (R.color.blue)
milosmns
Drawable drawable = ...; drawable.setColorFilter (ContextCompat.getColor (contexto, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (dibujable); // se puede usar cualquier color aquí
flame3

Respuestas:

916

Puede cambiar el tinte, bastante fácilmente en el código a través de:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // Tinte blanco

Si quieres tinte de color, entonces

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.MULTIPLY);

Para Vector Drawable

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.SRC_IN);

ACTUALIZACIÓN :
@ADev tiene una solución más nueva en su respuesta aquí , pero su solución requiere una biblioteca de soporte más nueva: 25.4.0 o superior.

Hardik
fuente
12
En xml, android: tint = "@ color / blue"
Luis
1
Plus android:
tint
8
android:tintFunciona en todas las versiones de Android. Tal vez estás hablando drawableTint?
finstas
11
PorterDuff.Mode.MULTIPLY no funciona en mi situación, utilicé PorterDuff.Mode.SRC_IN y funciona
Mohamed Nageh
235

La mayoría de las respuestas se refieren al uso setColorFilterque no es lo que se pidió originalmente.

El usuario @Tad tiene su respuesta en la dirección correcta, pero solo funciona en API 21+.

Para configurar el tinte en todas las versiones de Android, use ImageViewCompat:

ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(yourTint));

Tenga yourTinten cuenta que en este caso debe ser un "color int". Si tiene un recurso de color como R.color.blue, primero debe cargar el color int:

ContextCompat.getColor(context, R.color.blue);
ADev
fuente
66
Debería ser la respuesta aceptada. Tenga en cuenta que solo funciona en ImageViewinstancias xml con el tema AppCompat o en AppCompatImageViewsubclases.
Louis CAD
1
@ADev aprecia su solución, pero la pregunta se hizo en 2013 y ImageViewCompat y AppCompatImageView con v4 soportan lib 25.4.0 en junio de 2017 y 25.1.0 de diciembre de 2016 respectivamente :)
Hardik
1
@ADev, por supuesto, pero no ha mencionado correctamente en su respuesta que su solución es nueva y requiere una biblioteca de soporte más nueva 25.4.0 y superior porque con una versión más baja de lib de soporte, esta clase no está disponible, ¡así que nadie podría encontrarla! !! por cierto edité la respuesta :) buen día ...
Hardik
Esto no funciona en la API 16.
Tayyab Mazhar
49

Esto funciono para mi

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
toobsco42
fuente
sí, funcionó para mí también, sin el segundo parámetro ... también puede funcionarmImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad
votado y sin el segundo parámetro, funciona a las mil maravillas. Thx @ toobsco42
Ravi Vaniya
35

@Hardik tiene razón. El otro error en su código es cuando hace referencia a su color definido por XML. Pasó solo la identificación al setColorFiltermétodo, cuando debe usar la identificación para ubicar el recurso de color y pasar el recurso alsetColorFilter método. Reescribiendo su código original a continuación.

Si esta línea está dentro de su actividad:

imageView.setColorFilter(getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

De lo contrario, debe hacer referencia a su actividad principal:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

Tenga en cuenta que esto también es cierto para los otros tipos de recursos, como enteros, bools, dimensiones, etc. Excepto para la cadena, para la cual puede usar directamente getString()en su actividad sin la necesidad de llamar primerogetResources() (no me pregunte por qué) .

De lo contrario, su código se ve bien. (Aunque no he investigado setColorFilterdemasiado el método ...)

CrepeGoat
fuente
22

Después probé todos los métodos y no me funcionaron.

Obtengo la solución usando otro PortDuff.MODE.

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);
Catluc
fuente
14

Comenzando con Lollipop, también hay un método de tinte para BitmapDrawables que funciona con la nueva clase Palette:

public void setTintList (tinte ColorStateList)

y

public void setTintMode (PorterDuff.Mode tintMode)

En versiones anteriores de Android, ahora puede usar la biblioteca DrawableCompat

Tad
fuente
2
en realidad, la biblioteca de soporte lo admite. vea mi respuesta: stackoverflow.com/a/34479043/878126
desarrollador de Android
13

Mejor función de extensión simplificada gracias a ADev

fun ImageView.setTint(@ColorRes colorRes: Int) {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, colorRes)))
}

Uso:-

imageView.setTint(R.color.tintColor)
Manohar Reddy
fuente
¿Hay uno similar para el tinte de texto de Button / TextView?
Desarrollador de Android
¿te refieres al color o tinte del texto de la vista de texto para dibujar vista de texto?
Manohar Reddy
Me refiero a "tinte de texto". El color del texto. Pero creo que es bastante problemático, ya que el texto tiene un color para cada estado ... Por otra parte, ¿cómo es que funciona bien cuando configuro el color de acento ... Extraño ... ¿Es posible quizás establecer el color de acento en un botón específico (o TextView), programáticamente?
Desarrollador de Android el
12

Prueba esto. Debería funcionar en todas las versiones de Android que admite la biblioteca de soporte:

public static Drawable getTintedDrawableOfColorResId(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorRes int colorResId) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), ContextCompat.getColor(context, colorResId));
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorInt int color) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), color);
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, PorterDuff.Mode.SRC_IN);
    return wrapDrawable;
}

Puede usar cualquiera de los anteriores para que funcione.

Puede leer más características interesantes de DrawableCompat en los documentos, aquí .

desarrollador de Android
fuente
1
También tuve que hacer imageView.getBackground()para obtener el dibujable, porque imageView.getDrawable()estaba volviendo nulo.
Rock Lee
@RockLee asegúrese de haber utilizado src en la vista de imagen xml o setImageResource en el código
orelzion
esta es la manera perfecta de configurar el color de tinte para el fondo de la vista de imagen
leegor
11

Si su color tiene transparencia hexadecimal, use el siguiente código.

ImageViewCompat.setImageTintMode(imageView, PorterDuff.Mode.SRC_ATOP);
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(Color.parseColor("#80000000")));

Para borrar el tinte

ImageViewCompat.setImageTintList(imageView, null);
Sai
fuente
cuál es el tipo de "img"
Beyaz
1
@Beyaz imges de tipo ImageView.
Sai
10

Simple y una linea

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));
Gautam Surani
fuente
9

Como la primera respuesta no funcionó para mí:

//get ImageView
ImageView myImageView = (ImageView) findViewById(R.id.iv);

//colorid is the id of a color defined in values/colors.xml
myImageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorid)));

Esto solo parece funcionar en API 21+, pero para mí eso no fue un problema. Puede usar un ImageViewCompat para resolver ese problema, aunque.

Espero haber ayudado a alguien :-)

Felix
fuente
7

Comenzando en Lollipop, hay un método llamado ImageView#setImageTintList()que puedes usar ... la ventaja es que toma unColorStateList un solo color en lugar de un solo color, lo que hace que el tinte de la imagen sea consciente del estado.

En los dispositivos anteriores a Lollipop, puede obtener el mismo comportamiento al teñir el dibujable y luego configurarlo como la ImageViewimagen dibujable de la imagen:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);
Alex Lockwood
fuente
6
Random random=new Random;
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
ColorFilter cf = new PorterDuffColorFilter(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)),Mode.OVERLAY);

imageView.setImageResource(R.drawable.ic_bg_box);
imageView.setColorFilter(cf);
Pawan asati
fuente
6

Para establecer el tinte para una vista de imagen mediante programación en Android

Tengo dos métodos para Android:

1)

imgView.setColorFilter(context.getResources().getColor(R.color.blue));

2)

 DrawableCompat.setTint(imgView.getDrawable(),
                     ContextCompat.getColor(context, R.color.blue));

Espero haber ayudado a alguien :-)

Abhign01
fuente
4

Agregando a la respuesta de ADev (que en mi opinión es la más correcta), desde la adopción generalizada de Kotlin, y sus útiles funciones de extensión:

fun ImageView.setTint(context: Context, @ColorRes colorId: Int) {
    val color = ContextCompat.getColor(context, colorId)
    val colorStateList = ColorStateList.valueOf(color)
    ImageViewCompat.setImageTintList(this, colorStateList)
}

¡Creo que esta es una función que podría ser útil tener en cualquier proyecto de Android!

Cillian Myles
fuente
4

Descubrí que podemos usar el selector de color para tint attr:

mImageView.setEnabled(true);

activity_main.xml:

<ImageView
    android:id="@+id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_arrowup"
    android:tint="@color/section_arrowup_color" />

section_arrowup_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_enabled="true"/>
    <item android:color="@android:color/black" android:state_enabled="false"/>
    <item android:color="@android:color/white"/>
</selector>
NickUnuchek
fuente
Hola, no funciona para dibujos vectoriales ... ¿Alguna solución para lo mismo?
Manukumar
@Manukumar Use en app:srcCompatlugar de android:srcy agregue vectorDrawables.useSupportLibrary = truea la defaultConfigparte de su archivo build.gradle. Probado para funcionar bien en el emulador Kitkat.
Desarrollador de Android
3

No usar PoterDuff.Mode, usarlo setColorFilter()funciona para todos.

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));
Vikash Sharma
fuente
2

Como dijo @milosmns, deberías usar imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

Esta API necesita un valor de color en lugar de una identificación de recurso de color. Esa es la causa principal por la cual su declaración no funcionó.

HunkD
fuente
2

Llego tarde a la fiesta pero no vi mi solución arriba. También podemos configurar el color del tinte setImageResource()(mi minSdkVersion es 24).

Entonces, primero, debe crear un selector y guardarlo en la /drawablecarpeta de activos (lo llamo ic_color_white_green_search.xml)

<!-- Focused and not pressed -->
<item android:state_focused="true"
      android:state_pressed="false">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Focused and pressed -->
<item android:state_focused="true"
      android:state_pressed="true">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Default -->
<item android:drawable="@drawable/ic_search"/>

Luego configúrelo en un código como este:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)
Hesam
fuente
2

En caso de que quiera configurar el selector a su tinte:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));
Yusril Maulidan Raji
fuente
0

Solución de Kotlin usando la función de extensión, para configurar y desarmar el tinte:

fun ImageView.setTint(@ColorInt color: Int?) {
    if (color == null) {
        ImageViewCompat.setImageTintList(this, null)
        return
    }
    ImageViewCompat.setImageTintMode(this, PorterDuff.Mode.SRC_ATOP)
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
}
desarrollador de Android
fuente
-4

No es una respuesta exacta, sino una alternativa más simple:

  • Coloque otra vista encima de la imagen.
  • Cambie el valor alfa de la vista como desee (mediante programación) para obtener el efecto deseado.

Aquí hay un fragmento para eso:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:contentDescription="@string/my_description"
        android:scaleType="fitXY"
        android:src="@drawable/my_awesome_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:alpha="0.5"
        android:background="@color/my_blue_color"/>
</FrameLayout>
Shubham Chaudhary
fuente
esto se trata de tinte! no alfa que es por transparencia.
David
Pero eso termina actuando como un tinte. Deberías probarlo tú mismo. Esta es solo una forma de ver las cosas.
Shubham Chaudhary
@ShubhamChaudhary Sé que es tarde, pero ¿qué pasa si la imagen es png? Entonces, ¿no cambiará el fondo? También el alfa y el tinte son muy diferentes. El tinte es como el reemplazo de color, si no me equivoco. Sin intención de ofender. Solo trato de ayudar :)
KISHORE_ZE
Punto valido. Esta respuesta ayudó en mi caso. La esperanza también se adapta a los zapatos de otra persona.
Shubham Chaudhary