Android10版本的Laucnher3把图标相关的独立成了一个库,iconloaderlib,所以修改图标相关的类都在这个目录。
应用图标生成是com.android.launcher3.icons.BaseIconFactory.java的createIconBitmap方法定义的,所以在这里处理就可以实现图标圆角角度的调整。
private int sColors[] = {0xffff0000, 0xff00ff00, 0xff0000ff};
private int sColorIndex = 0;
/**
* 将图片截取为圆角图片
*
* @param bitmap 原图片
* @param ratio 截取比例,如果是8,则圆角半径是宽高的1/8,如果是2,则是圆形图片
* @return 圆角矩形图片,用户记得释放资源
*/
private Bitmap getRoundCornerBitmap(Context context, Bitmap bitmap, float ratio) {
// 出错处理
if (bitmap == null || bitmap.isRecycled()) {
return null;
}
// 图片宽高出错
int width = bitmap.getWidth();
int height = bitmap.getHeight();
if (width <= 0 || height <= 0) {
return null;
}
// 半径处理
if (ratio <= 0.0f) {
ratio = 1;
}
float scaleMax = mIconBitmapSize;
try {
// 边角处理
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
float rx = width / ratio;
float ry = height / ratio;
canvas.drawRoundRect(rectF, rx, ry, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
float scale = scaleMax / output.getWidth();
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
// 得到新的图片
Bitmap newbm = Bitmap.createBitmap(output, 0, 0, width, height, matrix, true);
return newbm;
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
/**
* @param icon drawable that should be flattened to a bitmap
* @param scale the scale to apply before drawing {@param icon} on the canvas
*/
public Bitmap createIconBitmap(Drawable icon, float scale, int size) {
boolean usRoundCorner = true;
if (usRoundCorner) {
int width = size;
int height = size;
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(mContext.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 = size;
int textureHeight = size;
Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
Bitmap.Config.ARGB_8888);
final Canvas canvas = mCanvas;
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);
}
mOldBounds.set(icon.getBounds());
icon.setBounds(left, top, left + width, top + height);
icon.draw(canvas);
icon.setBounds(mOldBounds);
canvas.setBitmap(null);
return getRoundCornerBitmap(mContext, bitmap, 132.0f / 28.0f);
} else {
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
if (icon == null) {
return bitmap;
}
mCanvas.setBitmap(bitmap);
mOldBounds.set(icon.getBounds());
if (ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) {
int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size),
Math.round(size * (1 - scale) / 2));
icon.setBounds(offset, offset, size - offset, size - offset);
icon.draw(mCanvas);
} else {
if (icon instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
Bitmap b = bitmapDrawable.getBitmap();
if (bitmap != null && b.getDensity() == Bitmap.DENSITY_NONE) {
bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics());
}
}
int width = size;
int height = size;
int intrinsicWidth = icon.getIntrinsicWidth();
int intrinsicHeight = icon.getIntrinsicHeight();
if (intrinsicWidth > 0 && intrinsicHeight > 0) {
// Scale the icon proportionally to the icon dimensions
final float ratio = (float) intrinsicWidth / intrinsicHeight;
if (intrinsicWidth > intrinsicHeight) {
height = (int) (width / ratio);
} else if (intrinsicHeight > intrinsicWidth) {
width = (int) (height * ratio);
}
}
final int left = (size - width) / 2;
final int top = (size - height) / 2;
icon.setBounds(left, top, left + width, top + height);
mCanvas.save();
mCanvas.scale(scale, scale, size / 2, size / 2);
icon.draw(mCanvas);
mCanvas.restore();
}
icon.setBounds(mOldBounds);
mCanvas.setBitmap(null);
return bitmap;
}
}
另外说一下,图标默认是有个白色背景的,如果需要去掉可以调整这个方法
private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, boolean shrinkNonAdaptiveIcons,
RectF outIconBounds, float[] outScale) {
float scale = 1f;
android.util.Log.e("Launcher3","normalizeAndWrapToAdaptiveIcon...");
//annotation for don't add white mask outshape when targetsdk >= 26
/*if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
if (mWrapperIcon == null) {
mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper)
.mutate();
}
AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon;
dr.setBounds(0, 0, 1, 1);
boolean[] outShape = new boolean[1];
scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape);
if (!(icon instanceof AdaptiveIconDrawable) && !outShape[0]) {
FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground());
fsd.setDrawable(icon);
fsd.setScale(scale);
icon = dr;
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor);
}
} else {
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
}*/
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
outScale[0] = scale;
return icon;
}
|