桌面图标icon替换客制图标。图标要比原始图标大,要求一致。应用图标去掉四周白边,保持原有比例。

/vendor/mediatek/proprietary/packages/apps/Launcher3/ src/com/android/launcher3/icons/IconCache.java

Q版本:,S版本的就setAppIconTheme方法里两句换成注释的,主要是entry.bitmap,entry没有这个bitmap属性会报错。

以下方法,s应该也适用,

Q版本的launcher3目录下

iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java:72:里面定义了这个CacheEntry类,继承了BitmapInfo

./iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java

这里面q就只定义了icon

    publicBitmap icon;
        public int color;

S上是quickstep/src/com/android/quickstep/TaskIconCache.java的TaskCacheEntry类

导包

    importandroid.content.ComponentName;
    importandroid.graphics.Bitmap;
    importandroid.graphics.BitmapFactory;
    importandroid.text.TextUtils;
    importcom.android.launcher3.R;
    importandroid.graphics.drawable.BitmapDrawable; 

这个是在Q版本放在这里使用,因为如果在setAppIconTheme方法里面加的话会出现切换系统语言后有些图标不更新的bug,但高版本没有这个bug.还有getIconFactory().createScaledBitmapWithoutShadow(d,true);之所以用到这个方法是让所有应用图标大小一致,不用的话,客制替换的图标太大了。不过这样子改完图标都变成很小了且有四周白边,再把图标撑满画布就行,不过这个时候比例不对,看起来很方不够圆润好看,需要修改比例,然后如果还嫌图标太小去src/com/android/launcher3/DeviceProfile.java。把图标大小调大点就可以。

在protectedvoid applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {

方法中加入

    String[]arr = mContext.getResources().getStringArray(R.array.icon_package);
            for (int i = 0; i < arr.length; i++){
                   if(getIconPackage(i).contains(info.getTargetComponent().getPackageName())){
                           Log.d("yantao","packageName("+ i+")="+getIconPackage(i));
                            Bitmap bitmap =BitmapFactory.decodeResource(mContext.getResources(),getIconId(i));
                           bitmap.setHasAlpha(true);
    Drawabled = new FixedSizeBitmapDrawable(bitmap);
                            entry.icon =getIconFactory().createScaledBitmapWithoutShadow(d,true);
                            //entry.icon = bitmap;
                    }
            }

实际上就是下面的setAppIconTheme方法,只不过不需要那么多参数,灵活变通,这个方法高版本,如S版本可以,放在

    privatesynchronized void getTitleAndIcon(
                @NonNull ItemInfoWithIconinfoInOut,
                @NonNullSupplier<LauncherActivityInfo> activityInfoProvider,
                boolean usePkgIcon, booleanuseLowResIcon) {
    applyCacheEntry(entry,infoInOut);之前加入
    setAppIconTheme(infoInOut.getTargetComponent(),activityInfoProvider,activityInfoProvider.get(),entry);

然后是用到的方法

    privatevoid setAppIconTheme(ComponentName componentName,
                                    Supplier<LauncherActivityInfo> infoProvider,
                                    LauncherActivityInfo info,
                                     CacheEntryentry){
            String[] arr =mContext.getResources().getStringArray(R.array.icon_package);
            for (int i = 0; i < arr.length; i++){
               if(getIconPackage(i).contains(componentName.getPackageName())){
                   Log.d("song","packageName("+ i+")="+getIconPackage(i));
     
                    Bitmap bitmap =BitmapFactory.decodeResource(mContext.getResources(),getIconId(i));
                    bitmap.setHasAlpha(true);
                    Drawable d= new FixedSizeBitmapDrawable(bitmap);
                 entry.bitmap= getIconFactory().createBadgedIconBitmap(d,info.getUser(),true);
                    return;
                }
            }

//entry.bitmap =getIconFactory().createBadgedIconBitmap(getFullResIcon(info),info.getUser(),true); //这句话不需要

    publicString getIconPackage(int i){
            String[] arr =mContext.getResources().getStringArray(R.array.icon_package);
            return arr[i];
        }
     
        public int getIconId(int i){
            String[] imageNameArr =mContext.getResources().getStringArray(R.array.icon_image);
            String imageName = null;
           if(!TextUtils.isEmpty(imageNameArr[i])){
                imageName =imageNameArr[i].substring(0, imageNameArr[i].indexOf("."));
            }
            int resId =mContext.getResources().getIdentifier(imageName, "drawable" ,mContext.getPackageName());
            return resId;
        }
    s上没有entry.icon的属性
    privatestatic class FixedSizeBitmapDrawable extends BitmapDrawable {
     
            public FixedSizeBitmapDrawable(Bitmapbitmap) {
                super(null, bitmap);
            }
     
            @Override
            public int getIntrinsicHeight() {
                return getBitmap().getWidth();
            }
     
            @Override
            public int getIntrinsicWidth() {
                return getBitmap().getWidth();
            }
        }

其实就是遍历数组获得对应的图片包名,把传进来对应的entry的图标换成由bitmap存放的客制图片,所以S上应该也可以直接替换不需要再FixedSizeBitmapDrawable

然后需要做一个array资源数组把包名和图片一一对应

./vendor/mediatek/proprietary/packages/apps/Launcher3/quickstep/res/values/config.xml

    <?xmlversion="1.0" encoding="utf-8"?>
    <resources>
     
        <string-arrayname="icon_package" translatable="false">
            <item>com.android.settings</item>
            <item>com.android.dialer</item>
         </string-array>
     
         <string-arrayname="icon_image" translatable="false">
           <item>ic_launcher_setting.png</item>
            <item>ic_launcher_dialer.png</item>
         </string-array>
    </resources>

然后放置资源图片

./vendor/mediatek/proprietary/packages/apps/Launcher3/quickstep/res/drawable/ ic_launcher_setting.png

注意这里之所以都放在quickstep,,是因为此项目带GMS,编译出的apk叫MtkLauncher3GoIconRecents,看mk文件生效的是quickstep里的资源,其他正常项目的话放在外面的res就可以,当然也可以放在特定密度,比如drawable-hdpi/

部分相关知识:

每次系统语言更新后接到广播就可以刷新图标,变成相应的语言

vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

    if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
                //If we have changed locale we need to clear out the labels in all apps/workspace.
               forceReload();

为啥要放在这个applyCacheEntry方法里:

Q版本为例:

里面有很多getTitleAndIcon方法,其中只有三个走到

其中public synchronized voidgetTitleAndIcon(ItemInfoWithIcon info,

LauncherActivityInfo activityInfo,boolean useLowResIcon) {

//这个标为1

第一个走到,然后传到下面这个必走

//这个标为3,这个方法是必走的

    privatesynchronized void getTitleAndIcon(
                @NonNull ItemInfoWithIconinfoInOut,
                @NonNullSupplier<LauncherActivityInfo> activityInfoProvider,
                boolean usePkgIcon, booleanuseLowResIcon) {
            CacheEntry entry =cacheLocked(infoInOut.getTargetComponent(), infoInOut.user,
                    activityInfoProvider,mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon);
            applyCacheEntry(entry, infoInOut);
        }

但是如果换了系统语言,再回到桌面,上面两个刚开始也会走,后面就是这个2来传给3

//这个标为2

publicsynchronized void getTitleAndIcon(ItemInfoWithIcon info, boolean useLowResIcon){

所以如果在3里更换icon,后面2传进来再跟新会有部分icon又回到默认的,关键是在于applyCacheEntry,所以只需要在这个方法每次都换掉icon就行

应用图标去掉四周白边:

这是加了GMS的走这个,实际看情况编的是vendor下的还是package下的

packages/apps/Launcher3/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java

源码

private staticfinal float LEGACY_ICON_SCALE = .7f * .6667f;

换成

private static finalfloat LEGACY_ICON_SCALE = 1.0f;

这个实际作用就是把图标中心往外撑大,1.0就是撑满画布。该属性控制图标缩放大小。源码把这个属性赋值

publicFixedScaleDrawable() {
        super(new ColorDrawable());
        mScaleX = LEGACY_ICON_SCALE;
        mScaleY = LEGACY_ICON_SCALE;
    }

然后保持原有比例:(在此之前会出现图标看上去很方正,不美观)

packages/apps/Launcher3/ iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java

private Drawable normalizeAndWrapToAdaptiveIcon(方法中

源码那套算法不要了

    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);
            }

全都注释掉

就用一句else里的加上就可以

scale =getNormalizer().getScale(icon, outIconBounds, null, null);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Youth King

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值