Launcher图标的替换这边介绍两种方式:
一、在Launcher中客制化替换桌面图标
其中第一种替换由于接近上层,所以替换之后可能会出现一些问题如:
图标大小不一致
数字角标被遮挡
近期任务/文件管理应用下图标未替换
......等bug。
虽然可以分别处理解决,但比较费事,效果欠佳。这边建议使用第二种,
但第一种能帮助我们学习Launcher的图标加载替换情况,是一个不错的学习总结,
可以根据自身需要学习和采纳!
链接:Launcher3图标客制化替换——在Launcher中客制化替换桌面图标
二、在Framwork层解析包时替换应用图标资源
1、涉及到的代码文件:
alps/frameworks/base/core/java/android/content/pm/parsing/ParsingPackageUtils.java //解析类
alps/frameworks/base/core/res/res/drawable/twitter_x.xml //矢量图资源,也可以是png类型的
alps/frameworks/libs/systemui/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java //去除系统自带的应用白框
/alps/frameworks/base/core/res/res/values/symbols.xml //资源声明
2、代码修改&解读
2.1 alps/frameworks/base/core/java/android/content/pm/parsing/ParsingPackageUtils.java 在这个类中,定义的方法:
private void parseBaseAppBasicFlags(ParsingPackage pkg, TypedArray sa) {
int targetSdk = pkg.getTargetSdkVersion();
//@formatter:off
// CHECKSTYLE:off
pkg
// Default true
.setAllowBackup(bool(true, R.styleable.AndroidManifestApplication_allowBackup, sa))
......
......
.setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa));
+ //JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 begin
+ if ("com.twitter.android".equals(pkgName)) {
+ pkg.setIconRes(com.android.internal.R.drawable.twitter_x);
+ } else if ("com.whatsapp".equals(pkgName)) {
+ pkg.setIconRes(com.android.internal.R.drawable.whatsappe);
+ }
+ //JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 end
// CHECKSTYLE:on
//@formatter:on
在解析应用程序的基本资源(标志)时,通过pkg获取到的包名,根据包名进行icon资源的替换。(如果替换的包名比较多可以建议进行代码优化:
1、创建一个包名工具类,通过HashMap完成包名和资源的映射:
/alps/frameworks/base/core/java/android/content/pm/parsing/PackageIconUtil.java
+package android.content.pm.parsing;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* SR_MMI:S702OP-493 modify for recent icon by zhongzhenhua add 2025.03.13
+* This method is intended for internal use only.
+* @hide
+*/
+public class PackageIconUtil {
+
+ public static final Map<String, Integer> PKG_ICON_MAP = new HashMap<>();
+
+ static {
+ PKG_ICON_MAP.put("com.twitter.android", com.android.internal.R.drawable.twitter_x);
+ PKG_ICON_MAP.put("com.whatsapp", com.android.internal.R.drawable.whatsapp);
+
+ }
+}
将之前的:ParsingPackageUtils.java解析类优化修改
......
.setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa));
+ String pkgName = pkg.getPackageName();
+ Slog.d(TAG, "pkgName = " + pkgName);
+ if (!TextUtils.isEmpty(pkgName)) {
+ Integer iconRes = PackageIconUtil.PKG_ICON_MAP.get(pkgName);
+ if (iconRes != null) {
+ pkg.setIconRes(iconRes);
+ }
)
2.2 alps/frameworks/base/core/res/res/drawable/twitter_x.xml准备好你需要的矢量图资源,之所以选择思量图,是因为它能够适配所有分辨率并且不失真保留清晰。当然png格式也可以,但可能会失真。
通过Android Studio转化成矢量图:
2.1.1 创建一个项目-选择drawable-单击右键-选择New-选择Vector Asset;如图
2.2.2 选择SVG或者PSD格式图标,根据需要调整大小。如图:
2.3 根据需要去除系统自带的应用白框,你也可以选择保留:alps/frameworks/libs/systemui/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
注释掉添加白框的代码位置即可。
- if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
+ //JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 begin
+ /**if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
if (mWrapperIcon == null) {
mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper)
.mutate();
@@ -245,9 +246,10 @@
((ColorDrawable) dr.getBackground()).setColor(mWrapperBackgroundColor);
}
- } else {
+ } else {*/
scale = getNormalizer().getScale(icon, outIconBounds, null, null);
- }
+ //}
+ //JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 end
2.4 资源文件的声明:/alps/frameworks/base/core/res/res/values/symbols.xml (务必声明,否则会编译报错)
+ <!--JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 begin-->
+ <java-symbol type="drawable" name="twitter_x" />
+ <java-symbol type="drawable" name="whatsapp" />
+ <!--JIRA:S702OP-493 modify for recent icon by zhongzhenhua 2025.03.12 end-->
<java-symbol type="drawable" name="sim_light_blue" />
<java-symbol type="drawable" name="sim_light_green" />