如何在 Android 中更改 Drawable 的颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1309629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change colors of a Drawable in Android?
提问by Matt McMinn
I'm working on an android application, and I have a drawable that I'm loading up from a source image. On this image, I'd like to convert all of the white pixels to a different color, say blue, and then cache the resultant Drawable object so I can use it later.
我正在开发一个 android 应用程序,我有一个可从源图像加载的可绘制对象。在此图像上,我想将所有白色像素转换为不同的颜色,例如蓝色,然后缓存生成的 Drawable 对象,以便稍后使用。
So for example say I have a 20x20 PNG file that has a white circle in the middle, and that everything outside the circle is transparent. What's the best way to turn that white circle blue and cache the results? Does the answer change if I want to use that source image to create several new Drawables (say blue, red, green, orange, etc)?
例如,假设我有一个 20x20 PNG 文件,中间有一个白色圆圈,圆圈外的所有内容都是透明的。将白色圆圈变成蓝色并缓存结果的最佳方法是什么?如果我想使用该源图像来创建几个新的 Drawable(比如蓝色、红色、绿色、橙色等),答案是否会改变?
I'm guessing that I'll want to use a ColorMatrix in some way, but I'm not sure how.
我猜我想以某种方式使用 ColorMatrix,但我不确定如何使用。
采纳答案by Matt McMinn
I was able to do this with the following code, which is taken from an activity (the layout is a very simple one, just containing an ImageView, and is not posted here).
我可以使用以下代码完成此操作,该代码取自一个活动(布局非常简单,仅包含一个 ImageView,此处未发布)。
private static final int[] FROM_COLOR = new int[]{49, 179, 110};
private static final int THRESHOLD = 3;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_colors);
ImageView iv = (ImageView) findViewById(R.id.img);
Drawable d = getResources().getDrawable(RES);
iv.setImageDrawable(adjust(d));
}
private Drawable adjust(Drawable d)
{
int to = Color.RED;
//Need to copy to ensure that the bitmap is mutable.
Bitmap src = ((BitmapDrawable) d).getBitmap();
Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
for(int x = 0;x < bitmap.getWidth();x++)
for(int y = 0;y < bitmap.getHeight();y++)
if(match(bitmap.getPixel(x, y)))
bitmap.setPixel(x, y, to);
return new BitmapDrawable(bitmap);
}
private boolean match(int pixel)
{
//There may be a better way to match, but I wanted to do a comparison ignoring
//transparency, so I couldn't just do a direct integer compare.
return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD &&
Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD &&
Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}
回答by thom_nic
I think you can actually just use Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )
. This would set white pixels to red but I don't think it would affect the transparent pixels.
我认为你实际上可以只使用Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )
. 这会将白色像素设置为红色,但我认为它不会影响透明像素。
回答by Naren
Give this code a try:
试试这个代码:
ImageView lineColorCode = (ImageView)convertView.findViewById(R.id.line_color_code);
int color = Color.parseColor("#AE6118"); //The color u want
lineColorCode.setColorFilter(color);
回答by MinceMan
I know this question was ask way before Lollipop but I would like to add a nice way to do this on Android 5.+. You make an xml drawable that references the original one and set tint on it like such:
我知道这个问题是在 Lollipop 之前问的,但我想在 Android 5.+ 上添加一个很好的方法来做到这一点。您制作了一个 xml 可绘制对象,该对象引用原始对象并在其上设置色调,如下所示:
<?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"/>
回答by Mike Hill
If you have a drawable that's a solid color and you want to change it to a differnet solid color, you can use a ColorMatrixColorFilter
. Transparency is preserved.
如果您有一个纯色的可绘制对象,并且想要将其更改为不同的纯色,则可以使用ColorMatrixColorFilter
. 透明度得以保留。
int iColor = Color.parseColor(color);
int red = (iColor & 0xFF0000) / 0xFFFF;
int green = (iColor & 0xFF00) / 0xFF;
int blue = iColor & 0xFF;
float[] matrix = { 0, 0, 0, 0, red,
0, 0, 0, 0, green,
0, 0, 0, 0, blue,
0, 0, 0, 1, 0 };
ColorFilter colorFilter = new ColorMatrixColorFilter(matrix);
drawable.setColorFilter(colorFilter);
回答by Pei
The new support v4 bring tint back to api 4.
新的支持 v4 将色调带回 api 4。
you can do it like this
你可以这样做
public static Drawable setTint(Drawable d, int color) {
Drawable wrappedDrawable = DrawableCompat.wrap(d);
DrawableCompat.setTint(wrappedDrawable, color);
return wrappedDrawable;
}
回答by sud007
I also use ImageView
for icons (in ListView
or settings screen). But I think there is much simpler way to do that.
我也ImageView
用于图标(在ListView
或设置屏幕中)。但我认为有更简单的方法可以做到这一点。
Use tint
to change the color overlay on your selected icon.
使用tint
来改变你的选择的图标颜色叠加。
In xml,
在xml中,
android:tint="@color/accent"
android:src="@drawable/ic_event"
works fine since it comes from AppCompat
工作正常,因为它来自 AppCompat
回答by hoangtu23
You should do this for all APIs:
您应该对所有 API 执行此操作:
Drawable myIcon = getResources().getDrawable( R.drawable.button );
ColorFilter filter = new LightingColorFilter( Color.BLACK, Color.BLACK);
myIcon.setColorFilter(filter);
回答by Ricard
You can solve it using Android support compat libraries. :)
您可以使用 Android 支持兼容库解决它。:)
// mutate to not share its state with any other drawable
Drawable drawableWrap = DrawableCompat.wrap(drawable).mutate();
DrawableCompat.setTint(drawableWrap, ContextCompat.getColor(getContext(), R.color.your_color))
回答by David Douglas
In your Activity you can tint your PNG image resources with a single colour:
在您的活动中,您可以使用单一颜色为 PNG 图像资源着色:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myColorTint();
setContentView(R.layout.activity_main);
}
private void myColorTint() {
int tint = Color.parseColor("#0000FF"); // R.color.blue;
PorterDuff.Mode mode = PorterDuff.Mode.SRC_ATOP;
// add your drawable resources you wish to tint to the drawables array...
int drawables[] = { R.drawable.ic_action_edit, R.drawable.ic_action_refresh };
for (int id : drawables) {
Drawable icon = getResources().getDrawable(id);
icon.setColorFilter(tint,mode);
}
}
Now when you use the R.drawable.* it should be coloured with the desired tint. If you need additional colours then you should be able to .mutate() the drawable.
现在,当您使用 R.drawable.* 时,它应该使用所需的色调进行着色。如果您需要其他颜色,那么您应该能够 .mutate() 可绘制对象。