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