Como definir tonalidade para uma visualização de imagem programaticamente no android?

396

Preciso definir tonalidade para uma visualização de imagem ... Estou usando da seguinte maneira:

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

Mas isso não muda ...

Alexander Farber
fonte
15
Você pode ter usado o ID do recurso inteiro em vez de valor de cor inteiro, tentar converter R.color.blue para getResources () GetColor (R.color.blue).
milosmns
Drawable drawable = ...; drawable.setColorFilter (ContextCompat.getColor (contexto, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (desenhável); // qualquer cor pode ser usada aqui
flame3

Respostas:

916

Você pode alterar a tonalidade facilmente no código via:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // Matiz branco

Se você quiser tonalidade de cor,

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

Para vetor Drawable

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

ATUALIZAÇÃO : O
@ADev possui uma solução mais nova em sua resposta aqui , mas sua solução requer uma biblioteca de suporte mais recente - 25.4.0 ou superior.

Hardik
fonte
12
No xml, android: tint = "@ color / blue"
Luis
11
Além disso, android: tint é 21+
androidguy 17/03/2017
8
android:tintfunciona em todas as versões do Android. Talvez você esteja falando drawableTint?
precisa saber é
11
PorterDuff.Mode.MULTIPLY não funciona na minha situação, usei o PorterDuff.Mode.SRC_IN e ele funciona #
Mohamed Nageh
234

A maioria das respostas se refere ao uso setColorFilterque não é o que foi originalmente solicitado.

O usuário @Tad tem sua resposta na direção certa, mas funciona apenas na API 21+.

Para definir a tonalidade em todas as versões do Android, use o ImageViewCompat:

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

Observe que yourTint, nesse caso, deve ser uma "cor int". Se você possui um recurso de cores R.color.blue, precisa primeiro carregar a cor int:

ContextCompat.getColor(context, R.color.blue);
ADev
fonte
6
Deve ser a resposta aceita. Observe que ele funciona apenas em ImageViewinstâncias xml com o tema AppCompat ou em AppCompatImageViewsubclasses.
Louis CAD
11
O @ADev aprecia sua solução, mas a pergunta foi feita em 2013 e o ImageViewCompat e o AppCompatImageView lançam com suporte à v4 lib 25.4.0 em junho de 2017 e 25.1.0 de dezembro de 2016, respectivamente :)
Hardik
11
@ADev, é claro, mas você não mencionou corretamente em sua resposta que sua solução é nova e requer uma biblioteca de suporte 25.4.0 e superior, porque com a versão inferior do suporte lib, essa classe não está disponível para que ninguém possa encontrá-la! !! a propósito, eu editei a resposta :) bom dia ... #
317
Isso não está funcionando na API 16.
Tayyab Mazhar
49

Isso funcionou para mim

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
toobsco42
fonte
sim, funcionou para mim também, sem o segundo parâmetro .. Pode também vaimImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad
votado e sem o segundo parâmetro, ele funciona como charme. Thx @ toobsco42
Ravi Vaniya
35

@Hardik está certo. O outro erro no seu código ocorre quando você faz referência à cor definida pelo XML. Você passou apenas o ID para o setColorFiltermétodo, quando deveria usá-lo para localizar o recurso de cores e passar o recurso para o métodosetColorFilter método. Reescrevendo seu código original abaixo.

Se esta linha estiver dentro da sua atividade:

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

Caso contrário, você precisa fazer referência à sua atividade principal:

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

Observe que isso também se aplica a outros tipos de recursos, como números inteiros, bools, dimensões, etc. Exceto pela string, para a qual você pode usar diretamente getString()em sua Atividade sem a necessidade de ligar primeiro.getResources() (não me pergunte por que) .

Caso contrário, seu código ficará bem. (Embora eu não tenha investigado setColorFiltermuito o método ...)

CrepeGoat
fonte
22

Depois que eu tentei todos os métodos e eles não funcionaram para mim.

Eu recebo a solução usando outro PortDuff.MODE.

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

A partir do Lollipop, também existe um método de tonalidade para o BitmapDrawables que funciona com a nova classe Palette:

público vazio setTintList (tonalidade ColorStateList)

e

public void setTintMode (PorterDuff.Mode tintMode)

Nas versões mais antigas do Android, agora você pode usar a biblioteca DrawableCompat

Tad
fonte
2
na verdade, a biblioteca de suporte é compatível. veja minha resposta: stackoverflow.com/a/34479043/878126
desenvolvedor android
12

Tente isso. Ele deve funcionar em todas as versões do Android suportadas pela biblioteca de suporte:

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;
}

Você pode usar qualquer um dos itens acima para fazê-lo funcionar.

Você pode ler sobre os recursos mais interessantes do DrawableCompat nos documentos, aqui .

desenvolvedor android
fonte
11
Eu também tive que fazer imageView.getBackground()para obter o drawable, porque imageView.getDrawable()estava retornando nulo.
Rock Lee
@RockLee ter certeza de que você usou src em vista imagem xml ou setImageResource em código
orelzion
esta é a maneira perfeita de cor da tonalidade conjunto para o fundo ImageView
leegor
12

Melhor função de extensão simplificada graças ao ADev

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

Uso:-

imageView.setTint(R.color.tintColor)
Manohar Reddy
fonte
Existe um similar para a tonalidade do texto do Button / TextView?
desenvolvedor android
você quer dizer a cor ou matiz do texto do textview?
Manohar Reddy
Quero dizer "tonalidade de texto". A cor do texto. Mas acho que é bastante problemático, pois o texto tem uma cor para cada estado ... Por outro lado, como funciona bem quando eu defino a cor de destaque ... Estranho ... É possível, talvez, definir a cor de destaque para um botão específico (ou TextView), programaticamente?
desenvolvedor android
11

Se sua cor tiver transparência hexadecimal, use o código abaixo.

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

Para limpar a tonalidade

ImageViewCompat.setImageTintList(imageView, null);
Sai
fonte
o que é "img" 's tipo
Beyaz
11
@Beyaz imgé do tipo ImageView.
Sai
10

Simples e uma linha

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

Como a primeira resposta não funcionou para mim:

//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)));

Isso parece funcionar apenas na API 21+, mas para mim isso não foi um problema. Você pode usar um ImageViewCompat para resolver esse problema.

Espero ter ajudado alguém :-)

Felix
fonte
7

A partir do Lollipop, existe um método chamado ImageView#setImageTintList()que você pode usar ... a vantagem é que ele leva um ColorStateListoposto a apenas uma única cor, tornando a tonalidade da imagem sensível ao estado.

Nos dispositivos pré-pirulito, você pode obter o mesmo comportamento pintando o drawable e, em seguida, definindo-o como o ImageViewdrawable da imagem:

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
fonte
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
fonte
6

Para definir tonalidade para uma imagem vista programaticamente no android

Eu tenho dois métodos para o Android:

1)

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

2)

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

Espero ter ajudado alguém :-)

Abhign01
fonte
4

Somando-se ADEV 's resposta (que na minha opinião é o mais correto), desde a adopção generalizada de Kotlin, e as suas funções de extensão úteis:

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

Eu acho que essa é uma função que pode ser útil em qualquer projeto do Android!

Cillian Myles
fonte
4

Descobri que podemos usar o seletor de cores para o atributo tint:

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
fonte
Oi, ele não está funcionando para desenhos vetoriais .. Alguma solução para o mesmo?
precisa saber é o seguinte
@Manukumar Use em app:srcCompatvez de android:srce adicione vectorDrawables.useSupportLibrary = truena defaultConfigparte do seu arquivo build.gradle. Testado para funcionar bem no emulador Kitkat.
desenvolvedor android
3

Não use PoterDuff.Mode, use setColorFilter()funciona para todos.

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

Como @milosmns disse, você deve usar imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

Essa API precisa de um valor de cor em vez do ID do recurso de cores. Essa é a causa principal da razão pela qual sua declaração não funcionou.

HunkD
fonte
2

Estou atrasado na festa, mas não vi minha solidão acima. Também podemos definir a cor da tonalidade setImageResource()(meu minSdkVersion é 24).

Então, primeiro, você precisa criar um seletor e salvá-lo na /drawablepasta de ativos (eu chamo de 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"/>

Em seguida, defina-o em código como este:

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

Caso você queira definir o seletor para a sua tonalidade:

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

Solução Kotlin usando a função de extensão, para definir e desabilitar a coloração:

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))
}
desenvolvedor android
fonte
-4

Resposta não exata, mas uma alternativa mais simples:

  • Coloque outra vista em cima da imagem
  • Altere o valor alfa da visualização da maneira que desejar (programaticamente) para obter o efeito desejado.

Aqui está um trecho para isso:

<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
fonte
isso é sobre tonalidade! não alfa que é para transparência.
David
Mas isso acaba agindo como uma tonalidade. Você deve tentar você mesmo. Esta é apenas uma maneira de ver as coisas.
Shubham Chaudhary
@ShubhamChaudhary Eu sei que isso é tarde, mas e se a imagem for png. Então o fundo não mudará? Alfa e matiz também são muito diferentes. Matiz É como substituição de cor, se não estiver errado. Nenhuma ofensa pretendida. Apenas tentando ajudar :)
KISHORE_ZE
Ponto válido. Esta resposta ajudou no meu caso. A esperança também se encaixa nos sapatos de outra pessoa.
Shubham Chaudhary