Програмно змінюйте кольори, що малюються


139

Я намагаюся змінити колір на зображенні білого маркера за кодом. Я читав, що код нижче повинен змінити колір, але мій маркер залишається білим.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Я щось пропустив? Чи є інший спосіб змінити кольори моїх малюнків, розташованих у моїй папці res?


загальноприйнятий відповідь не робота для me..used це Як відповісти [1], [1]: stackoverflow.com/questions/5940825 / ...
sham.y

Я думаю, що всі відповіді тут змінюють колір фону, але не колір зображення. Я прав? хтось може мені сказати, будь ласка? Я спробував усі рішення тут, а також на ті самі запитання щодо stackoverflow, але вони можуть змінювати лише колір тла на випадок. Тому я думаю, ми можемо змінити лише колір тла, але не колір зображення. Я маю рацію?
Shirish Herwade

Відповіді:


258

Спробуйте це:

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

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


Хм, колір залишається білим. Чи може це стосуватися OverlayItemsкласу привіт mapview, який може спричинити проблему? Це регулярне виведення з моєї папки res, нічого особливого ...
Йохан

так що було рішенням?
speedynomads

@ ρyaσѕρєяK Ви дуже awesome.very
полезно

30
Ви можете віддати перевагу PorterDuff.Mode.SRC_IN, якщо ви хочете, щоб він працював із ширшим діапазоном кольорів джерела.
Lorne Laliberte

1
Конструктор PorterDuffColorFilter приймає кольоровий формат
ARGB

124

Ви можете спробувати це для вектору, що малюється SVG

DrawableCompat.setTint(
    DrawableCompat.wrap(myImageView.getDrawable()),
    ContextCompat.getColor(context, R.color.another_nice_color)
);

4
Найкращий спосіб, який я бачив для svg.
apSTRK

1
віддайте перевагу цьому над прийнятою відповіддю, хоча обидва будуть працювати, але з цим мені не потрібно турбуватися про те, що можна встановити, я просто отримаю той, який вже є, і він також сумісний назад, чудово!
RJFares

1
Найкраща відповідь, коли нічого не працює, як шарм! Дуже дякую! Примітка. Це також працює, коли у вашому imageView / AppCompatImageView є Xml, який можна малювати
Sjd

1
Як її видалити програмно?
Хардік Джоші

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"/>

Це підійде для вас, якщо у вас є обмежена кількість кольорів, які ви хочете використовувати на своїх малюнках. Перегляньте мій пост у блозі для отримання додаткової інформації .


2
Приємно! До речі, це, здається, працює чудово і на попередньому Lollipop. (Тільки тестували це на пристрої minSdkVersion 16та Android 4.1.1.)
Jonik

Створюючи растрову карту таким чином, вона не розтягується, щоб відповідати макеті, як це було б при використанні android:background="...". Досить дивно!
Князь

Я думаю, що це тому, що ви не створюєте дев'ять патчів тут.
MinceMan

Вибачте, ця сторінка не існує = (
Phan Van Linh

@Jonik Відповіді на поставлене запитання не мають значення. Це питання задає для способу змінити Drawable кольору «s, а НЕ ImageView.
Антоній.H

19

Ви можете спробувати це для ImageView. використовуючи setColorFilter().

imageViewIcon.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));

10

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

Ця функція повертає можливість переходу.

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

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 Ласкаво просимо до 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)

Зауважте, код тут - Котлін.


3

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

Я пропоную оглянути композицію на сайті Mozilla тут. (У них немає всіх режимів, які працює андроїд, але їх багато)


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, якщо ваш фон має закруглені кути тощо.


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: значення аргументів кольорів.


Це буде працювати лише в тому випадку, якщо ОП використовує imageViews замість малюнків.
Посів Fiber

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.