Android 里的 Adaptive Icon 的内在

自从 Android 系统引入自适应图标,创建快捷方式的时,就多了一个可以设置的方法,即 IconCompat 里的 createWithAdaptiveBitmap 方法,而在此之前,为快捷方式设置图标位图的方法仅是 createWithBitmap

根据对自适应图标的认知,它应该是分为前景和背景两层的,但是上述的新旧两个方法,却都是只接收一个参数。难道一个类型为 Bitmap 的参数是可以容纳两块图像的吗?由此好奇,只好先看一下 createWithAdaptiveBitmap 方法的实现:

并未看出端倪,只不过是在新建对象时指定了相应的类型而已。由于 IconCompat 仅是系统 Icon 类的浅封装,所以还是要继续看。果不其然,在 toIcon 方法中,对于 TYPE_ADAPTIVE_BITMAP 类型,如果判断系统支持,则会调用 Icon.createWithAdaptiveBitmap 方法。接下来要去系统源码里看了,我看的是线上的:aospxref.com 站点

在 Icon 类的内部,可以找到一个叫 loadDrawableInner 的方法,可以看到它是如何分别把对应于非自适应的传统图标和自适应图标的位图转换为 Drawable 对象的。节略如下:

可见,位图被传递到了 AdaptiveIconDrawable 对象中,而构建该对象时,构造函数中的第一个参数——通过查看其原型可知——应该是用来指定其背景 Drawable 对象的,被设置为了 null

由上可知,Android 系统在传递自适应图标的图像时,采取了一种很不周到的方案,可以说是违背了其设计初衷。正确的方式,哪怕不想在所有的相关方法中增加一个单独的参数用于设置背景,至少也应该将这唯一的 Bitmap 对象进行一种变通改造,使其宽度或者高度倍增(显然是高度更为适宜),将背景一并容纳在内,由接收方收到后进行必要的尺寸检查,然后将该位图再拆为前景和背景两个部分进行绘制。

发表回复

您的电子邮箱地址不会被公开。