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.