因为 android的第三方图标不规则,公司这边会要求统一加一个标准背板。但是如果所有的图标都加一个会显得单调,所以我采用读取第三方图标的颜色,然后添加相应的背景。
修改图标背景的文件是在Launcher3文件夹下的Utilities.java下的 createIconBitmap 函数里,原始函数为:
public static Bitmap createIconBitmap(Drawable icon, Context context) {
synchronized (sCanvas) {
final int iconBitmapSize = getIconBitmapSize();
int width = iconBitmapSize;
int height = iconBitmapSize;
if (icon instanceof PaintDrawable) {
PaintDrawable painter = (PaintDrawable) icon;
painter.setIntrinsicWidth(width);
painter.setIntrinsicHeight(height);
} else if (icon instanceof BitmapDrawable) {
// Ensure the bitmap has a density.
BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
Bitmap bitmap = bitmapDrawable.getBitmap();
if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics());
}
}
int sourceWidth = icon.getIntrinsicWidth();
int sourceHeight = icon.getIntrinsicHeight();
if (sourceWidth > 0 && sourceHeight > 0) {
// Scale the icon proportionally to the icon dimensions
final float ratio = (float) sourceWidth / sourceHeight;
if (sourceWidth > sourceHeight) {
height = (int) (width / ratio);
} else if (sourceHeight > sourceWidth) {
width = (int) (height * ratio);
}
}
// no intrinsic size --> use default size
int textureWidth = iconBitmapSize;
int textureHeight = iconBitmapSize;
final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
Bitmap.Config.ARGB_8888);
final Canvas canvas = sCanvas;
canvas.setBitmap(bitmap);
final int left = (textureWidth-width) / 2;
final int top = (textureHeight-height) / 2;
@SuppressWarnings("all") // suppress dead code warning
final boolean debug = false;
if (debug) {
// draw a big box for the icon for debugging
canvas.drawColor(sColors[sColorIndex]);
if (++sColorIndex >= sColors.length) sColorIndex = 0;
Paint debugPaint = new Paint();
debugPaint.setColor(0xffcccc00);
canvas.drawRect(left, top, left+width, top+height, debugPaint);
}
sOldBounds.set(icon.getBounds());
icon.setBounds(left, top, left+width, top+height);
icon.draw(canvas);
icon.setBounds(sOldBounds);
canvas.setBitmap(null);
return bitmap;
}
}
修改方法是,给他返回的bitmap添加相应的边框 ,把最末尾的:
return bitmap;
改为 :
return addBorderToImage(bitmap, iconBitmapSize);
关键地方就是这个 addBorderToImage 的实现:
private static float mRoundedRate = 7f; //圆角的角度
private static Bitmap addBorderToImage(Bitmap src, int iconSize) {
int width = iconSize;//getBorderWidth();
int height = iconSize;//getBorderHeight();
Bitmap output = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
RectF outerRect = new RectF(0,0,width,height);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
LinearGradient mLinearGradientClamp = new LinearGradient(0, 0, 0, height, new int[] {getCenterTopColor(src),getCenterBottomColor(src)}, null, TileMode.CLAMP);
paint.setShader(mLinearGradientClamp);
canvas.drawRoundRect(outerRect, width/mRoundedRate, height/mRoundedRate, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
int sw = src.getWidth();
int sh = src.getHeight();
Rect srcRect = new Rect(0,0,sw,sh);
Rect dstRect = getDstRect(sw,sh,width,height);
canvas.drawBitmap(src, srcRect, dstRect, paint);
return output;
}
private static Rect getDstRect( int sw,int sh,int w,int h){
return new Rect(0,0,w,h);
}
/**
* 得到原始图片中,底部中间的第一个完全不透明的颜色
* @return
*/
private static int getCenterTopColor(Bitmap src){
int w = src.getWidth();
int h = src.getHeight();
int x = (int) (w*0.5);
int c = Color.WHITE;
for(int y =h-1;y>=0;--y){
int pixel = src.getPixel(x, y);
if(Color.alpha(pixel)==0xFF){
c = pixel;
}
}
return softColor(c);
}
/**
* 得到原始图片中,顶部中间的第一个完全不透明的颜色
* @return
*/
private static int getCenterBottomColor(Bitmap src){
int w = src.getWidth();
int h = src.getHeight();
int x = (int) (w*0.5);
int c = Color.WHITE;
for(int y =0;y<h;++y){
int pixel = src.getPixel(x, y);
if(Color.alpha(pixel)==0xFF){
c = pixel;
}
}
return softColor(c);
}
/**
* 将颜色变浅,变淡
* @param color
* @return
*/
private static int softColor(int color){
int r = (int) (Color.red(color)*1.3);
int b = (int) (Color.blue(color)*1.3);
int g = (int) (Color.green(color)*1.3);
int af = 0xFF;
if(b >= 0xFF){
b = 0xFF;
}
if(r>=0xFF){
r = 0xFF;
}
if(g>=0xFF){
g = 0xFF;
}
return af<<24|r<<16|g<<8|b;
}