所谓的 Adaptive Icon,其实就是拥有前景和背景两个 Drawale 的对象,把它们依次重叠绘制出就好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class IconUtil { public static Bitmap getAppIcon(PackageManager mPackageManager, String packageName) { try { Drawable drawable = mPackageManager.getApplicationIcon(packageName); if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } else if (drawable instanceof AdaptiveIconDrawable) { Drawable background = ((AdaptiveIconDrawable) drawable).getBackground(); Drawable foreground = ((AdaptiveIconDrawable) drawable).getForeground(); LayerDrawable layerDrawable = new LayerDrawable(new Drawable[2] { background, foreground }); int width = layerDrawable.getIntrinsicWidth(); int height = layerDrawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); layerDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); layerDrawable.draw(canvas); return bitmap; } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; } } |
(上面的代码其实漏了对图标轮廓/形状的处理。在 setBounds
之前,理应加入
1 2 3 4 |
<span class="hljs-type"> AdaptiveIconDrawable</span> <span class="hljs-variable">adaptiveIconDrawable</span> <span class="hljs-operator">=</span> (AdaptiveIconDrawable) drawable; Path path = new Path(); adaptiveIconDrawable.getIconMask().getOutline(new Outline().getPath(path)); canvas.clipPath(path); // 裁剪 canvas 以保持透明部分 |
,更新于 2024-08-01)
不过这个方案看着专业,其实略显繁复。既然 AdaptiveIconDrawable
也是 Drawable
,那大一统岂不美哉,
1 2 3 4 5 6 7 8 |
@NonNull private Bitmap getBitmapFromDrawable(@NonNull Drawable drawable) { final Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); final Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } |
不过要注意,有些 Drawable
是不会返回宽高信息的,例如纯色;另外,如果传进来的是个 BitmapDrawable
,那就别再费劲画了,直接返回 getBitmap()
就好。