Программное изменение цвета для рисования

139

Я пытаюсь изменить цвет на изображении белого маркера по коду. Я прочитал, что код ниже должен изменить цвет, но мой маркер остается белым.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Я что-то пропустил? Есть ли другой способ изменить цвета на моих чертежах, расположенных в моей папке res?

Johan
источник
принятый ответ не сработал для меня .. использовал это Как ответить [1], [1]: stackoverflow.com/questions/5940825/…
sham.y
Я думаю, что все ответы здесь меняют цвет фона, но не цвет изображения. Я прав? кто-нибудь может сказать мне, пожалуйста? Я пробовал все решения здесь, а также по тем же вопросам о stackoverflow, но в некоторых случаях они меняют только цвет фона. Поэтому я думаю, что мы можем изменить только цвет фона, но не цвет изображения. Я прав?
Шириш Хервэйд

Ответы:

259

Попробуй это:

Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.my_drawable); 
Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(wrappedDrawable, Color.RED);    

Использование DrawableCompatважно, поскольку оно обеспечивает обратную совместимость и исправляет ошибки на устройствах с API 22 и ранее.

ρяσѕρєя K
источник
Хм, цвет остается белым. Может ли это быть связано с OverlayItemsклассом hello mapview, который может вызвать проблему? Его можно вытащить из моей папки res, ничего особенного ...
Йохан
так какое было решение?
speedynomads
@ ρяσѕρєяK вы очень классные. очень полезные
luttu android
30
Вы можете предпочесть PorterDuff.Mode.SRC_IN, если хотите, чтобы он работал с более широким диапазоном исходных цветов.
Lorne Laliberte
1
Конструктор PorterDuffColorFilter принимает цветовой формат ARGB
RichX
124

Вы можете попробовать это для svg vector drawable

DrawableCompat.setTint(
    DrawableCompat.wrap(myImageView.getDrawable()),
    ContextCompat.getColor(context, R.color.another_nice_color)
);
amorenew
источник
4
Лучший способ, который я видел для svg.
apSTRK
1
предпочитаю это принятому ответу, хотя оба будут работать, но с этим мне не нужно беспокоиться о том, что можно установить, я просто получаю тот, который уже есть, и он также обратно совместим, отлично!
RJFares
1
Лучший ответ, когда ничего не работает, но работает как шарм! Большое спасибо! Примечание: это также работает, когда у вас есть XML-файл, который можно
рисовать
1
Как удалить программно?
Hardik Joshi
1
@HardikJoshi В документации сказано: Чтобы очистить оттенок, перейдите nullкDrawable#setTintList(ColorStateList)
arekolek
23

Возможно, вам придется вызвать mutate () для рисования, иначе это повлияет на все значки.

Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_my_icon).mutate();
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.colorIcon, typedValue, true);
icon.setColorFilter(typedValue.data, PorterDuff.Mode.SRC_ATOP);
Шики
источник
21

Другой способ сделать это на Lollipop, android 5. + - установить оттенок растрового изображения, которое можно рисовать, например:

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_back"
    android:tint="@color/red_tint"/>

Это сработает для вас, если у вас есть ограниченное количество цветов, которые вы хотите использовать в своих чертежах. Прочтите мой блог для получения дополнительной информации .

MinceMan
источник
2
Ницца! Кстати, это, похоже, отлично работает и на pre-Lollipop. (Только что протестировал это с minSdkVersion 16устройством Android 4.1.1.)
Jonik
При создании растрового изображения таким образом оно не растягивается для соответствия макету, как при использовании android:background="...". Довольно странно!
Prince
Я думаю, это потому, что вы не создаете здесь патч девятки.
MinceMan
Извините, эта страница не существует = (
Phan Van Linh
@Jonik Ответы на предоставленный вами вопрос неуместны. Этот вопрос спрашивает, как изменить цвет Drawable , а не ImageView.
Antony.H 02
19

Вы можете попробовать это для ImageView. используя setColorFilter().

imageViewIcon.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));
Джайдип Мегхапара
источник
10

Я написал общую функцию, в которой вы можете передать контекст, значок - это значок изображения id / mipmap и новый цвет, который вам нужен для этого значка.

Эта функция возвращает drawable.

public static Drawable changeDrawableColor(Context context,int icon, int newColor) {
    Drawable mDrawable = ContextCompat.getDrawable(context, icon).mutate(); 
    mDrawable.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_IN)); 
    return mDrawable;
} 

changeDrawableColor(getContext(),R.mipmap.ic_action_tune, Color.WHITE);
Сачин Танпуре
источник
9

Вы можете попробовать ColorMatrixColorFilter, так как ваш ключевой цвет белый:

// Assuming "color" is your target color
float r = Color.red(color) / 255f;
float g = Color.green(color) / 255f;
float b = Color.blue(color) / 255f;

ColorMatrix cm = new ColorMatrix(new float[] {
        // Change red channel
        r, 0, 0, 0, 0,
        // Change green channel
        0, g, 0, 0, 0,
        // Change blue channel
        0, 0, b, 0, 0,
        // Keep alpha channel
        0, 0, 0, 1, 0,
});
ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
myDrawable.setColorFilter(cf);
tiguchi
источник
7

Это сработало для меня. Не забудьте поставить «ff» между 0x и цветовым кодом. Как это 0xff2196F3

Drawable mDrawable = ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_vector_home);
                    mDrawable.setColorFilter(new
                            PorterDuffColorFilter(0xff2196F3,PorterDuff.Mode.SRC_IN));
Bek
источник
Привет, @Bek, добро пожаловать в stackoverflow. Если это сработает для вас, было бы очень полезно включить jsfiddle с минимальным решением, чтобы показать это. Это поможет человеку, задавшему вопрос, правильно понять.
Арджун Чаудхари
6

То же, что и принятый ответ, но более простой удобный метод:

val myDrawable = ContextCompat.getDrawable(context, R.drawable.my_drawable)
myDrawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN)
setCompoundDrawablesWithIntrinsicBounds(myDrawable, null, null, null)

Обратите внимание, код здесь - Kotlin.

CorayThan
источник
3

Вы можете попробовать Mode.LIGHTENили Mode.DARKEN. Документация Android Javadocs ужасно объясняет, что делают режимы PorterDuff. Вы можете ознакомиться с ними здесь: PorterDuff | Android

Я предлагаю посмотреть здесь Compositing на сайте Mozilla . (У них нет всех режимов, которые есть в Android, но у них их много)

sebsebmc
источник
3

Используйте это: для java

view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_OVER)

для Котлина

view.background.setColorFilter(Color.parseColor("#343434"),PorterDuff.Mode.SRC_OVER)

вы можете использовать PorterDuff.Mode.SRC_ATOP, если ваш фон имеет закругленные углы и т. д.

Ravi.Dudi
источник
1

Синтаксис

"your image name".setColorFilter("your context".getResources().getColor("color name"));

пример

myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));
Ом Пракаш Шарма
источник
0

Вот что я сделал:

public static Drawable changeDrawableColor(int drawableRes, int colorRes, Context context) {
    //Convert drawable res to bitmap
    final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableRes);
    final Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth() - 1, bitmap.getHeight() - 1);
    final Paint p = new Paint();
    final Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, p);

    //Create new drawable based on bitmap
    final Drawable drawable = new BitmapDrawable(context.getResources(), resultBitmap);
    drawable.setColorFilter(new
            PorterDuffColorFilter(context.getResources().getColor(colorRes), PorterDuff.Mode.MULTIPLY));
    return drawable;
}
Эдвин
источник
0

Просто используйте

    android:drawableTint="@color/primary_color"

в вашем XML-файле. Заменить primary_color на собственный цвет

Арвина Кори
источник
0

Создайте такой метод:

//CHANGE ICON COLOR
private void changeIconColor(Context context ,int drawable){
    Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, drawable);
    assert unwrappedDrawable != null;
    Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
    DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.colorAccent));
}

и используйте это так:

    changeIconColor(this,R.drawable.ic_home);
сана эбади
источник
0

Самый простой способ сделать это:

imageView.setColorFilter(Color.rgb(r, g b));

или

imageView.setColorFilter(Color.argb(a, r, g, b));

a, r, g, b: значения argb цвета.

Анубхав
источник
Это будет работать только в том случае, если OP будет использовать imageViews вместо чертежей.
SowingFiber
0

Для тех, кто использует Kotlin, простая функция расширения:

fun Drawable.tint(context: Context,  @ColorRes color: Int) {
    DrawableCompat.setTint(this, context.resources.getColor(color, context.theme))
}

а потом просто сделай

background.tint(context, R.color.colorPrimary)
Chapz
источник