Jak ustawić odcień dla widoku obrazu programowo w Androidzie?


396

Muszę ustawić odcień dla widoku obrazu ... Używam go w następujący sposób:

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

Ale to się nie zmienia ...


15
Być może użyłeś identyfikatora zasobu liczby całkowitej zamiast wartości koloru całkowitego, spróbuj przekonwertować R.color.blue na getResources (). GetColor (R.color.blue)
milosmns

Wyciągany ciągnienia = ...; drawable.setColorFilter (ContextCompat.getColor (kontekst, R.color.biały), PorterDuff.Mode.DST); imageView.setImageDrawable (rysowany); // można tutaj użyć dowolnego koloru
flame3

Odpowiedzi:


916

Możesz zmienić odcień, dość łatwo w kodzie poprzez:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // biały odcień

Jeśli chcesz odcień koloru, to

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

Do rysowania wektorowego

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

AKTUALIZACJA :
@ADev ma nowsze rozwiązanie w swojej odpowiedzi tutaj , ale jego rozwiązanie wymaga nowszej biblioteki wsparcia - 25.4.0 lub wyższej.



12
W xml android: tint = "@ color / blue"
Luis

1
Plus android: odcień to 21+
androidguy

8
android:tintdziała na wszystkich wersjach Androida. Może mówisz o drawableTint?
finstas,

11
PorterDuff.Mode.MULTIPLY nie działa w mojej sytuacji użyłem PorterDuff.Mode.SRC_IN i działa
Mohamed Nageh

234

Większość odpowiedzi odnosi się do używania, setColorFilterktóre nie jest tym, o co pierwotnie pytano.

Użytkownik @Tad ma swoją odpowiedź we właściwym kierunku, ale działa tylko na API 21+.

Aby ustawić odcień we wszystkich wersjach Androida, użyj ImageViewCompat:

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

Zauważ, że yourTintw tym przypadku musi być „int kolor”. Jeśli masz taki zasób koloru R.color.blue, musisz najpierw załadować kolor int:

ContextCompat.getColor(context, R.color.blue);

6
Powinna być zaakceptowana odpowiedź. Zauważ, że działa tylko na ImageViewinstancjach xml z kompozycją AppCompat lub na AppCompatImageViewpodklasach.
Louis

1
@ ADev doceniamy twoje rozwiązanie, ale pytanie zostało zadane w 2013 r. Oraz ImageViewCompat i AppCompatImageView wersja z obsługą v4 lib 25.4.0 odpowiednio w czerwcu 2017 r. I 25.1.0 grudnia 2016 r.
Hardik

1
@ ADev oczywiście, ale nie wspomniałeś o tym poprawnie w odpowiedzi, że twoje rozwiązanie jest nowe i wymaga nowszej biblioteki wsparcia 25.4.0 i wyższej, ponieważ przy niższej wersji lib wsparcia ta klasa nie jest dostępna, więc nikt nie mógł jej znaleźć !! !! tak przy okazji, zredagowałem odpowiedź :) dzień dobry ...
Hardik

To nie działa na API 16.
Tayyab Mazhar

49

To zadziałało dla mnie

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));

tak, pracowałem też dla mnie, bez drugiego parametru .. to też może pójśćmImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad

pozytywnie oceniany i bez drugiego parametru działa jak urok. Dzięki @ toobsco42
Ravi Vaniya

35

@Hardik ma rację. Innym błędem w kodzie jest odniesienie do koloru zdefiniowanego w XML. Przekazałeś tylko identyfikator do setColorFiltermetody, kiedy powinieneś użyć identyfikatora do zlokalizowania zasobu kolorów i przekazać zasób do setColorFiltermetody. Przepisz swój oryginalny kod poniżej.

Jeśli ten wiersz mieści się w Twojej aktywności:

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

W przeciwnym razie musisz odwołać się do swojej głównej działalności:

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

Zauważ, że dotyczy to również innych rodzajów zasobów, takich jak liczby całkowite, boole, wymiary itp. Z wyjątkiem łańcucha, do którego możesz bezpośrednio użyć getString()w swojej aktywności bez konieczności pierwszego połączenia getResources()(nie pytaj mnie dlaczego) .

W przeciwnym razie kod wygląda dobrze. (Chociaż nie badałem setColorFilterzbytnio tej metody ...)


22

Po wypróbowaniu wszystkich metod i one nie działały dla mnie.

Otrzymuję rozwiązanie za pomocą innego PortDuff.MODE.

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


12

Spróbuj tego. Powinien działać na wszystkich wersjach Androida obsługiwanych przez bibliotekę wsparcia:

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

Możesz użyć dowolnego z powyższych, aby to działało.

O ciekawszych funkcjach DrawableCompat można przeczytać w dokumentacji tutaj .


1
Musiałem także zrobić, imageView.getBackground()aby uzyskać możliwość losowania, ponieważ zwracał imageView.getDrawable()zero.
Rock Lee

@RockLee upewnij się, że użyłeś src w widoku obrazu xml lub setImageResource w kodzie
orelzion

jest to idealny sposób na ustawienie koloru odcienia tła
podglądu obrazu

12

Lepsza uproszczona funkcja rozszerzenia dzięki ADev

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

Stosowanie:-

imageView.setTint(R.color.tintColor)

Czy istnieje podobny odcień tekstu przycisku / TextView?
programista Androida

masz na myśli kolor tekstu lub odcień tekstu w widoku tekstowym do rysowania?
Manohar Reddy

Mam na myśli „odcień tekstu”. Kolor tekstu. Ale myślę, że jest to dość problematyczne, ponieważ tekst ma kolor dla każdego stanu ... Z drugiej strony, jak to działa, kiedy ustawiam kolor akcentu ... Dziwne ... Czy to możliwe, że można ustawić kolor akcentu na konkretny przycisk (lub TextView), programowo?
programista Androida

11

Jeśli kolor ma przezroczystość szesnastkową, użyj poniższego kodu.

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

Aby usunąć odcień

ImageViewCompat.setImageTintList(imageView, null);

jaki jest typ „img”
Beyaz

1
@Beyaz imgjest typu ImageView.
Sai

10

Prosta i jedna linia

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));

9

Ponieważ pierwsza odpowiedź nie zadziałała dla mnie:

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

Wydaje się, że działa to tylko w API 21+, ale dla mnie to nie był problem. Do rozwiązania tego problemu można użyć ImageViewCompat.

Mam nadzieję, że pomogłem komukolwiek :-)


7

Począwszy od Lollipop, istnieje metoda o nazwie ImageView#setImageTintList(), której można użyć ... zaletą jest to, że zajmuje ona ColorStateListzamiast jednego koloru, dzięki czemu odcień obrazu jest rozpoznawany przez stan.

Na urządzeniach z wersją wcześniejszą niż Lollipop można uzyskać takie samo zachowanie, odbarwiając obszar do rysowania, a następnie ustawiając go jako ImageViewobraz do rysowania:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);

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

6

Do ustawiania odcienia dla widoku obrazu programowo w Androidzie

Mam dwie metody dla Androida:

1)

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

2)

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

Mam nadzieję, że pomogłem komukolwiek :-)


4

Dodając do ADev „s odpowiedź (co moim zdaniem jest najbardziej poprawne), od powszechnego przyjęcia Kotlin, a jej użytecznych funkcji rozszerzających:

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

Myślę, że jest to funkcja, która może być przydatna w każdym projekcie na Androida!


4

Zauważyłem, że możemy użyć selektora kolorów dla atrybutu 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>

Cześć, to nie działa dla wektorowych drawables .. Jakieś obejście tego samego?
Manukumar

@Manukumar Użyj app:srcCompatzamiast android:srci dodaj vectorDrawables.useSupportLibrary = truedo defaultConfigczęści pliku build.gradle. Przetestowano pod kątem poprawnego działania na emulatorze KitKat.
programista Androida

3

Nie używaj PoterDuff.Mode, użyj setColorFilter()działa dla wszystkich.

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

2

Jak powiedział @mosmosmns, powinieneś użyć imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

Ten interfejs API wymaga wartości koloru zamiast identyfikatora zasobu koloru. Jest to główna przyczyna, dla której twoje polecenie nie działa.


2

Jestem spóźniony na przyjęciu, ale nie widziałem powyżej mojego rozwiązania. Jesteśmy również w stanie ustawić kolor odcienia setImageResource()(moja minSdkVersion to 24).

Najpierw musisz utworzyć selektor i zapisać go w /drawablefolderze zasobów (nazywam to 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"/>

Następnie ustaw go w taki sposób:

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

2

W przypadku, gdy chcesz ustawić selektor na swój odcień:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));

0

Rozwiązanie Kotlin wykorzystujące funkcję rozszerzenia do ustawiania i wyłączania barwienia:

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

-4

Nie dokładna odpowiedź, ale prostsza alternatywa:

  • Umieść inny widok na górze obrazu
  • Zmień wartość alfa widoku, jak chcesz (programowo), aby uzyskać pożądany efekt.

Oto fragment tego:

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

chodzi o odcień! nie alfa dla przejrzystości.
David

Ale to ostatecznie działa jak odcień. Powinieneś spróbować sam. To tylko jeden sposób patrzenia na rzeczy.
Shubham Chaudhary

@ShubhamChaudhary Wiem, że jest późno, ale co, jeśli obraz jest png. W takim razie tło się nie zmieni? Również alfa i odcień są bardzo różne. Odcień jest jak zamiana kolorów, jeśli się nie mylę. Żadne przestępstwo nie jest zamierzone. Próbuję tylko pomóc :)
KISHORE_ZE,

Ważny punkt Ta odpowiedź pomogła w moim przypadku. Nadzieja pasuje również do butów innych osób.
Shubham Chaudhary
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.