Launcher图标白边

问题背景

有的桌面图标有白边,图标被缩放的很小。

问题原因

1、为了统一图标形状
2、图标形状可以配置系统的IconMask,修改圆形或者正方形或者水滴等等

launcher图标加载
1、加载应用图标

packages\apps\Launcher3\src\com\android\launcher3\model\LoaderTask.java

private List<LauncherActivityInfo> loadAllApps() {
	...
	mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
	...
}
2、packages\apps\Launcher3\src\com\android\launcher3\model\AllAppsList.java
    public void add(AppInfo info, LauncherActivityInfo activityInfo) {
        ...
        mIconCache.getTitleAndIcon(info, activityInfo, true);
        ...
    }
3、packages\apps\Launcher3\src\com\android\launcher3\icons\IconCache.java

getTitleAndIcon方法的cacheLocked里面处理图标

    private synchronized void getTitleAndIcon(
            @NonNull ItemInfoWithIcon infoInOut,
            @NonNull Supplier<LauncherActivityInfo> activityInfoProvider,
            boolean usePkgIcon, boolean useLowResIcon) {
        CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), infoInOut.user,
                activityInfoProvider, mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon);
        applyCacheEntry(entry, infoInOut);
    }
4、launcher图标的获取和裁剪在iconloaderlib模块

frameworks\libs\systemui\iconloaderlib\src\com\android\launcher3\icons\cache\BaseIconCache.java
cacheLocked方法,调用frameworks\libs\systemui\iconloaderlib\src\com\android\launcher3\icons\cache\CachingLogic.java的loadIcon
真正的实现在packages\apps\Launcher3\src\com\android\launcher3\icons\LauncherActivityCachingLogic.java

    @Override
    public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) {
        try (LauncherIcons li = LauncherIcons.obtain(context)) {
            return li.createBadgedIconBitmap(new IconProvider(context)
                            .getIcon(object, li.mFillResIconDpi),
                    object.getUser(), object.getApplicationInfo().targetSdkVersion);
        }
    }

通过保存Drawable到本地发现new IconProvider(context).getIcon(object, li.mFillResIconDpi)拿到的图标是ok的。
也就是说图标的处理在li.createBadgedIconBitmap内部。

5、public class LauncherIcons extends BaseIconFactory

frameworks\libs\systemui\iconloaderlib\src\com\android\launcher3\icons\BaseIconFactory.java的createBadgedIconBitmap方法里,通用一步一步打印保存bitmap到本地,发现是

icon = normalizeAndWrapToAdaptiveIcon(icon, shrinkNonAdaptiveIcons, null, scale);//这个方法改变了图标的形状,把各种各样的图标改成了符合系统图标形状的样子
    private Drawable normalizeAndWrapToAdaptiveIcon(@NonNull Drawable icon,
            boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) {
        if (icon == null) {
            return null;
        }
        float scale = 1f;
        Log.i("cheyingkun","normalizeAndWrapToAdaptiveIcon 111 : "+isMyIcon);

        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];
            //缩放比例1
            scale = getNormalizer().getScale(icon, outIconBounds, dr.getIconMask(), outShape);
            Log.d("cheyingkun","normalizeAndWrapToAdaptiveIcon 222 scale: "+scale);
            if (!(icon instanceof AdaptiveIconDrawable) && !outShape[0]) {
                FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground());
                fsd.setDrawable(icon);
                fsd.setScale(scale);
                icon = dr;
                //缩放比例2
                scale = getNormalizer().getScale(icon, outIconBounds, null, null);
                Log.d("cheyingkun","normalizeAndWrapToAdaptiveIcon 333 scale: "+scale);
                //这里设置的白色背景
                ((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor);
            }
        } else {
            scale = getNormalizer().getScale(icon, outIconBounds, null, null);
            Log.d("cheyingkun","normalizeAndWrapToAdaptiveIcon 444 scale: "+scale);
        }

        outScale[0] = scale;
        return icon;
    }
6、FixedScaleDrawable 中
//把这个缩放比例改为1f
private static final float LEGACY_ICON_SCALE = 1f;//.7f * .6667f;
    @Override
    public void draw(Canvas canvas) {
        int saveCount = canvas.save();
        canvas.scale(mScaleX, mScaleY,
                getBounds().exactCenterX(), getBounds().exactCenterY());
        super.draw(canvas);
        canvas.restoreToCount(saveCount);
    }

最终图标呈现细节在draw中的缩放比例。

7、frameworks\base\graphics\java\android\graphics\drawable\AdaptiveIconDrawable.java
private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);

AdaptiveIconDrawable会对前景图做裁剪,而不是等比例缩放。所以会导致没有适配AdaptiveIconDrawable的应用图标可能被裁剪掉。

也不能直接修改AdaptiveIconDrawable里的DEFAULT_VIEW_PORT_SCALE ,会导致Google应用图标前景图异常小。

总结

图标的处理还是在iconloaderlib中。
BaseIconFactory.java的normalizeAndWrapToAdaptiveIcon处理了图标形状和白色背景。
里面有几个缩放比例,调整会影响桌面图标大小和白色背景。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值