如何在Android中更改Drawable的颜色?

我正在一个Android应用程序,我有一个绘图,我从源图像加载。 在这个图像上,我想将所有的白色像素转换成不同的颜色,比如蓝色,然后caching合成的Drawable对象,以便稍后使用它。

所以例如说我有一个20×20的PNG文件,中间有一个白色圆圈,圆圈外的所有东西都是透明的。 将白色圆圈变成蓝色并caching结果的最佳方法是什么? 如果我想使用该源图像创build几个新的Drawable(比如蓝色,红色,绿色,橙色等),答案会改变吗?

我猜我想用某种方式使用ColorMatrix,但我不知道如何。

我想你实际上可以使用Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY ) 。 这将白色像素设置为红色,但我不认为这会影响透明像素。

请参阅Drawable#setColorFilter

试试这个代码:

 ImageView lineColorCode = (ImageView)convertView.findViewById(R.id.line_color_code); int color = Color.parseColor("#AE6118"); //The color u want lineColorCode.setColorFilter(color); 

如果您有一个可绘制的纯色,并且想要将其更改为不同的纯色,则可以使用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); 

我知道这个问题是在棒棒糖之前问的方式,但我想添加一个很好的方式来做到这一点在Android 5 +。 你创build一个xml drawable来引用原始的,并在其上设置色调,如下所示:

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

看看我的博客文章了解更多信息 。

新的支持v4带来色彩回api 4。

你可以这样做

 public static Drawable setTint(Drawable d, int color) { Drawable wrappedDrawable = DrawableCompat.wrap(d); DrawableCompat.setTint(wrappedDrawable, color); return wrappedDrawable; } 

你应该为所有的API做到这一点:

 Drawable myIcon = getResources().getDrawable( R.drawable.button ); ColorFilter filter = new LightingColorFilter( Color.BLACK, Color.BLACK); myIcon.setColorFilter(filter); 

我的天啊! 很多很好的答案,我也使用ImageView的图标(在列表视图或设置屏幕)。 但是我觉得有这么简单的方法可以做到这一点

使用“色调”来更改所选图标上的颜色叠加层。

在XML我做到了这一点

机器人:色调=“@颜色/重音”
机器人:SRC = “@绘制/ ic_event”

工作正常,因为它来自appCompat! 干杯!

我能够用下面的代码来做到这一点,这是从一个活动(布局是一个非常简单的,只是包含一个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; } 

在您的活动中,您可以使用单一色彩为您的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); } } 

现在,当您使用R.drawable。*时,应该用所需的色调进行着色。 如果你需要额外的颜色,那么你应该能够.mutate()drawable。

 Drawable drawable = DrawableCompat.wrap(drawable); drawable.mutate(); // to not share its state with any other drawable DrawableCompat.setTint(drawable, ContextCompat.getColor(getContext(), R.color.your_color)); 

看看这个示例代码“ ColorMatrixSample.java ”

 /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.graphics; import com.example.android.apis.R; import android.app.Activity; import android.content.Context; import android.graphics.*; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; public class ColorMatrixSample extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private ColorMatrix mCM = new ColorMatrix(); private Bitmap mBitmap; private float mSaturation; private float mAngle; public SampleView(Context context) { super(context); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.balloons); } private static void setTranslate(ColorMatrix cm, float dr, float dg, float db, float da) { cm.set(new float[] { 2, 0, 0, 0, dr, 0, 2, 0, 0, dg, 0, 0, 2, 0, db, 0, 0, 0, 1, da }); } private static void setContrast(ColorMatrix cm, float contrast) { float scale = contrast + 1.f; float translate = (-.5f * scale + .5f) * 255.f; cm.set(new float[] { scale, 0, 0, 0, translate, 0, scale, 0, 0, translate, 0, 0, scale, 0, translate, 0, 0, 0, 1, 0 }); } private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) { float scale = contrast + 1.f; float translate = (-.5f * scale + .5f) * 255.f; cm.set(new float[] { 1, 0, 0, 0, translate, 0, 1, 0, 0, translate, 0, 0, 1, 0, translate, 0, 0, 0, 1, 0 }); } private static void setContrastScaleOnly(ColorMatrix cm, float contrast) { float scale = contrast + 1.f; float translate = (-.5f * scale + .5f) * 255.f; cm.set(new float[] { scale, 0, 0, 0, 0, 0, scale, 0, 0, 0, 0, 0, scale, 0, 0, 0, 0, 0, 1, 0 }); } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; float x = 20; float y = 20; canvas.drawColor(Color.WHITE); paint.setColorFilter(null); canvas.drawBitmap(mBitmap, x, y, paint); ColorMatrix cm = new ColorMatrix(); mAngle += 2; if (mAngle > 180) { mAngle = 0; } //convert our animated angle [-180...180] to a contrast value of [-1..1] float contrast = mAngle / 180.f; setContrast(cm, contrast); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint); setContrastScaleOnly(cm, contrast); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint); setContrastTranslateOnly(cm, contrast); paint.setColorFilter(new ColorMatrixColorFilter(cm)); canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10), paint); invalidate(); } } } 

相关的API可以在这里find :

有这么多的解决scheme,但没有人提出,如果颜色资源XML文件已经有颜色,那么我们可以直接从那里select也如下:

 ImageView imageView = (ImageView) findViewById(R.id.imageview); imageView.setColorFilter(getString(R.color.your_color)); 

这与所有与背景的工作:

Textview,Button …

 TextView text = (TextView) View.findViewById(R.id.MyText); text.setBackgroundResource(Icon); text.getBackground().setColorFilter(getResources().getColor(Color), PorterDuff.Mode.SRC_ATOP); 
 view.getDrawable().mutate().setColorFilter(0xff777777, PorterDuff.Mode.MULTIPLY); 

感谢@sabadow

这个代码片段为我工作:

 PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(getResources().getColor(R.color.your_color),PorterDuff.Mode.MULTIPLY); imgView.getDrawable().setColorFilter(porterDuffColorFilter); imgView.setBackgroundColor(Color.TRANSPARENT) 

根据isWorking字段更改可绘制颜色的简短示例。

我的形状xml:

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="@android:color/holo_blue_bright" /> <corners android:radius="30dp" /> <size android:height="15dp" android:width="15dp" /> </shape> 

我的方法来改变:

 private Drawable getColoredDrawable(int drawableResId, boolean isworking) { Drawable d = getResources().getDrawable(R.drawable.shape); ColorFilter filter = new LightingColorFilter( isworking ? Color.GREEN : Color.RED, isworking ? Color.GREEN : Color.RED); d.setColorFilter(filter); return d; } 

使用示例:

 text1.setCompoundDrawablesWithIntrinsicBounds(getColoredDrawable(R.drawable.shape, isworking()), null, null, null); 

当你使用一个图书馆来为你做这件事情时非常简单。 试试这个: https : //github.com/jrvansuita/IconHandler

你可以这样打电话:

 Icon.on(holderView).color(R.color.your_color).icon(R.mipmap.your_icon).put();