Как установить оттенок для просмотра изображений программно в Android?

398

Нужно установить оттенок для изображения ... Я использую его следующим образом:

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

Но это не меняет ...

Александр Фарбер
источник
15
Возможно, вы использовали целочисленный идентификатор ресурса вместо целочисленного значения цвета, попробуйте преобразовать R.color.blue в getResources (). GetColor (R.color.blue)
milosmns
Drawable Drawable = ...; drawable.setColorFilter (ContextCompat.getColor (context, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (вытяжка); // здесь можно использовать любой цвет
flame3

Ответы:

918

Вы можете легко изменить оттенок в коде с помощью:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // Белый оттенок

Если вы хотите цветовой оттенок, то

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

Для векторного Drawable

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

ОБНОВЛЕНИЕ :
@ADev имеет более новое решение в своем ответе здесь , но его решение требует более новой библиотеки поддержки - 25.4.0 или выше.

Hardik
источник
1
Дополнительная информация: публичный финал void setColorFilter (int color, PorterDuff.Mode mode)
Джон
12
В xml, android: tint = "@ color / blue"
Луис
1
Плюс андроид: оттенок 21+
androidguy
8
android:tintработает на всех версиях Android. Может ты о чем drawableTint?
finstas
11
PorterDuff.Mode.MULTIPLY не работает в моей ситуации, я использовал PorterDuff.Mode.SRC_IN, и это работает
Мохамед Наге
236

Большинство ответов относятся к использованию, setColorFilterа не к тому, что было задано изначально.

Пользователь @Tad имеет свой ответ в правильном направлении, но он работает только на API 21+.

Чтобы установить оттенок на всех версиях Android, используйте ImageViewCompat:

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

Обратите внимание, что yourTintв этом случае должен быть «цвет int». Если у вас есть такой цветовой ресурс R.color.blue, вам нужно сначала загрузить цвет int:

ContextCompat.getColor(context, R.color.blue);
ADEV
источник
6
Должен быть принятый ответ. Обратите внимание, что он работает только на ImageViewэкземплярах XML с темой AppCompat или на AppCompatImageViewподклассах.
Louis CAD
1
@ADev признателен за ваше решение, но вопрос был задан в 2013 году и выпуски ImageViewCompat и AppCompatImageView с версией v4 lib 25.4.0 в июне 2017 года и 25.1.0 декабря 2016 года соответственно :)
Hardik
1
@ADev, конечно, но вы не упомянули правильно в своем ответе, что ваше решение является новым и требует более новой библиотеки поддержки 25.4.0 и выше, потому что с более низкой версией поддержки lib этот класс недоступен, поэтому никто не мог его найти !! !! кстати я отредактировал ответ :) добрый день ...
Хардик
Это не работает на API 16.
Тайяб Мажар
50

Это сработало для меня

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
toobsco42
источник
да, у меня тоже сработало, без второго параметра .. может тоже идетmImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Бискрем Мухаммед
проголосовал и без второго параметра, он работает как шарм. Thx @ toobsco42
Рави Вания
35

@ Хардик это правильно. Другая ошибка в вашем коде - это когда вы ссылаетесь на свой определенный XML цвет. Вы прошли только идентификатор к setColorFilterспособу, когда вы должны использовать идентификатор , чтобы найти цвет ресурс и передать ресурс к setColorFilterметоду. Переписав свой оригинальный код ниже.

Если эта строка находится в вашей деятельности:

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

Иначе, вам нужно указать свою основную деятельность:

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

Обратите внимание, что это также относится и к другим типам ресурсов, таким как целые числа, bools, измерения и т. Д. За исключением строки, которую вы можете напрямую использовать getString()в своей Деятельности без необходимости первого вызова getResources()(не спрашивайте меня, почему) ,

В противном случае ваш код выглядит хорошо. (Хотя я не слишком исследовал setColorFilterметод ...)

CrepeGoat
источник
22

После того, как я попробовал все методы, и они не работали для меня.

Я получаю решение с помощью другого PortDuff.MODE.

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);
Catluc
источник
14

Начиная с леденец, есть также Оттенок метод BitmapDrawables , который работает с новым классом Palette:

public void setTintList (ColorStateList tint)

а также

public void setTintMode (PorterDuff.Mode tintMode)

В старых версиях Android вы теперь можете использовать библиотеку DrawableCompat

Тэд
источник
2
на самом деле, библиотека поддержки поддерживает его. см. мой ответ: stackoverflow.com/a/34479043/878126
разработчик Android
13

Лучшая упрощенная функция расширения благодаря ADev

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

Применение:-

imageView.setTint(R.color.tintColor)
Манохар Редди
источник
Есть ли аналогичный для оттенка текста Button / TextView?
разработчик Android
Вы имеете в виду текстовый цвет textview или оттенок для textview?
Манохар Редди
Я имею в виду «текстовый оттенок». Цвет текста. Но я думаю, что это довольно проблематично, так как текст имеет цвет для каждого состояния ... Опять же, как получается, что он прекрасно работает, когда я устанавливаю цвет акцента ... Странно ... Возможно ли установить цвет акцента на конкретная кнопка (или TextView), программно?
разработчик Android
12

Попробуй это. Он должен работать на всех версиях Android, которые поддерживает библиотека поддержки:

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

Вы можете использовать любой из вышеперечисленных, чтобы заставить его работать.

Вы можете прочитать о более интересных функциях DrawableCompat в документации здесь .

разработчик Android
источник
1
Я также должен был сделать imageView.getBackground()drawable, потому что imageView.getDrawable()возвращал ноль.
Рок Ли
@RockLee, убедитесь, что вы использовали src в представлении изображений xml или setImageResource в коде
orelzion
это идеальный способ установить оттенок цвета фона изображения
leegor
11

Если ваш цвет имеет прозрачность в шестнадцатеричном формате, используйте код ниже.

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

Очистить оттенок

ImageViewCompat.setImageTintList(imageView, null);
Sai
источник
что такое тип "img"
Ucdemir
1
@Beyaz imgимеет тип ImageView.
Саи
10

Простая и одна строчка

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));
Гаутам Сурани
источник
9

Как первый ответ не работал для меня:

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

Кажется, это работает только в API 21+, но для меня это не было проблемой. Вы можете использовать ImageViewCompat для решения этой проблемы, хотя.

Я надеюсь, что я помог никому :-)

Феликс
источник
7

Начиная с Lollipop, существует метод, ImageView#setImageTintList()который вы можете использовать ... преимущество в том, что он требуетColorStateList а не только один цвет, таким образом, делая оттенок изображения чувствительным к состоянию.

На устройствах, предшествующих Lollipop, вы можете получить то же поведение, подкрашивая нарисованный объект, а затем устанавливая его как ImageViewрисунок для рисования:

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

Для установки оттенка для просмотра изображений программно в Android

У меня есть два метода для Android:

1)

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

2)

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

Я надеюсь, что я помог никому :-)

Abhign01
источник
4

Добавление к ADEV «s ответ (который , по моему мнению , является наиболее правильным), поскольку широкое внедрение Котлин, и его полезных функций расширения:

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

Я думаю, что эта функция может быть полезна в любом проекте Android!

Киллиан Майлз
источник
4

Я обнаружил, что мы можем использовать селектор цвета для оттенка 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
источник
Привет, это не работает для векторных объектов. Любой обходной путь для того же?
Манукумар
@Manukumar Используйте app:srcCompatвместо android:srcи добавьте vectorDrawables.useSupportLibrary = trueв свою defaultConfigчасть файла build.gradle. Протестировано для работы на эмуляторе Kitkat.
Android-разработчик
3

Не используйте PoterDuff.Mode, используйте setColorFilter()это работает для всех.

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));
Викаш Шарма
источник
2

Как сказал @milosmns, вы должны использовать imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

Для этого API нужно значение цвета вместо идентификатора ресурса цвета. Это основная причина, по которой ваше утверждение не сработало.

HunkD
источник
2

Я опаздываю на вечеринку, но я не видел своего решения выше. Мы также можем установить оттенок цвета setImageResource()(мой minSdkVersion равен 24).

Итак, во-первых, вам нужно создать селектор и сохранить его в /drawableпапке активов (я называю это 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"/>

Затем установите его в коде так:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)
Hesam
источник
2

Если вы хотите установить селектор на ваш оттенок:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));
Юсрил Маулидан Раджи
источник
0

Решение Kotlin с использованием функции расширения для установки и отмены тонирования:

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))
}
разработчик Android
источник
-4

Не точный ответ, а более простая альтернатива:

  • Поместите другой вид сверху изображения
  • Измените альфа- значение представления так, как вы хотите (программно), чтобы получить желаемый эффект.

Вот фрагмент для этого:

<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>
Шубхам Чаудхари
источник
это о оттенке! не альфа, что для прозрачности.
Дэвид
Но это в конечном итоге действует как оттенок. Вы должны попробовать это сами. Это всего лишь один из способов взглянуть на вещи.
Шубхам Чаудхари
@ShubhamChaudhary Я знаю, что уже поздно, но что, если изображение png. Тогда не изменится ли фон? Также альфа и оттенок очень разные. Оттенок - это как замена цвета, если я не ошибаюсь. Без обид. Просто пытаюсь помочь :)
KISHORE_ZE
Действительная точка. Этот ответ помог в моем случае. Надежда подходит и к чужой обуви.
Шубхам Чаудхари