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