Как установить оттенок для просмотра изображений программно в 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 или выше.



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

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

да, у меня тоже сработало, без второго параметра .. может тоже идет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метод ...)


22

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

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

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

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 в документации здесь .


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

что такое тип "img"
— Ucdemir

1
@Beyaz imgимеет тип ImageView.
— Саи


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

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


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>

Привет, это не работает для векторных объектов. Любой обходной путь для того же?
— Манукумар

@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 нужно значение цвета вместо идентификатора ресурса цвета. Это основная причина, по которой ваше утверждение не сработало.


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)


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

-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

Действительная точка. Этот ответ помог в моем случае. Надежда подходит и к чужой обуви.
— Шубхам Чаудхари
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.