Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动安卓桌面
布局配置
布局配置文件路径:
Go 版本:Launcher3\go\res\xml\device_profiles.xml
非 Go 版本:Launcher3\res\xml\device_profiles.xml
配置文件中定义了不同分辨率对应的 grid-option 和 display-option 标签,Launcher 根据设备分辨率自适
应最佳 UI 配置,通常情况下无需调整(go版本)需求来说明这个文件:
appwidget(待机界面小部件)
favorite(待机界面应用图标)
screen 页面位置 packageName 包名 className 类名
x X坐标位置 y Y坐标位置
folder(待机界面文件夹)
resolve(待机界面图标)
<resolve
launcher:container="-101"
launcher:screen="1"
launcher:x="1"
launcher:y="0" >
</resolve>
其中,-101 代表 Hotseat,-100 代表 Workspace。screen 页面位置,也是 Hotseat 自左到右的顺序位置。X 坐标位置,也是 Hotseat 自左到右的顺序位置,与 screen 一致。Y 坐标位置,由于 Hotseat 只有一行,故默认一直是 0。
图标客制化
Hotseat 应用图标名称显示
Hotseat 区域,应用图标名称默认隐藏,若需显示,请按照下列步骤进行修改:
步骤 1 显示 Hotseat 应用图标名称
Launcher3\src\com\android\launcher3\CellLayout.java
// Hotseat icons - remove text
if (child instanceof BubbleTextView) {
BubbleTextView bubbleChild = (BubbleTextView) child;
- bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
+ bubbleChild.setTextVisibility(true);
}
步骤 2 显示 Hotseat 区域文件夹图标名称
Launcher3\src\com\android\launcher3\WorkspaceLayoutManager.java
// Hide folder title in the hotseat
if (child instanceof FolderIcon) {
- ((FolderIcon) child).setTextVisible(false);
+ ((FolderIcon) child).setTextVisible(true);
}
步骤 3 调整 Hotseat 图标大小
修改完成后,若发现 Hotseat 图标名称显示不全,需要调整 Hotseat 大小,使图标名称显示完全。
Launcher3\res\values\dimens.xml
- <dimen name="dynamic_grid_hotseat_extra_vertical_size">34dp</dimen>
+ <dimen name=" dynamic_grid_hotseat_extra_vertical_size">48dp</dimen>
注意,处理此需求需要谨慎,修改会压缩workspace空间
隐藏某个图标
在 Launcher 中隐藏某个应用图标及其 widget,以达到预期效果。目前,Launcher 已经预留了隐藏某个
应用的接口类,具体如下:
Launcher3\src\com\android\launcher3\AppFilter.java
步骤 1 新增一个类继承于接口类:
例如:Launcher3\src\com\android\launcher3\CustomAppFilter.java
package com.android.launcher3;
import android.content.ComponentName;
import android.content.Context;
public class CustomAppFilter extends AppFilter {
public CustomAppFilter(Context context) {
}
@Override
public boolean shouldShowApp(ComponentName app) {
// 实现此方法即可过滤相应的应用图标
if (app.getPackageName().equals("com.android.calendar")) {
return false;
}
return true;
}
}
步骤 2 在配置文件中配置该类:
Launcher3\res\values\config.xml
<!-- Various classes overriden by projects/build flavors. -->
- <string name="app_filter_class" translatable="false"></string>
+ <string name="app_filter_class"
translatable="false">com.android.launcher3.CustomAppFilter</string>
步骤 3 混淆:该子类为隐式启动,其他地方没有调用,在编译过程中会被忽略。需要做如下修改,避免被
忽略。
Launcher3\proguard.flags
+ -keep class com.android.launcher3.CustomAppFilter {
+ *;
+ }
桌面(Go)布局的开发
LauncherProvider.java
synchronized private void loadDefaultFavoritesIfNecessary() {
String regionMark = SystemProperties.get("ro.boot.regionmark", "");
String euexcountry = SystemProperties.get("ro.boot.oplus.euex", "");
String operator = SystemProperties.get("ro.boot.operator", "");
StringBuffer sb = new StringBuffer();
String oppoDefaultLayout = "";
if (!"NULL".equals(operator) && !TextUtils.isEmpty(regionMark)) {
oppoDefaultLayout = sb.append(Partner.RES_DEFAULT_LAYOUT).append("_").append(regionMark).append("_").append(operator).toString();
} else if (!TextUtils.isEmpty(regionMark) && "NULL".equals(operator) && "NULL".equals(euexcountry)) {
oppoDefaultLayout = sb.append(Partner.RES_DEFAULT_LAYOUT).append("_").append(regionMark).toString();
} else if (!"NULL".equals(euexcountry) && !TextUtils.isEmpty(regionMark)) {
oppoDefaultLayout = sb.append(Partner.RES_DEFAULT_LAYOUT).append("_").append(regionMark).append("_").append(euexcountry).toString();
} else {
oppoDefaultLayout = Partner.RES_DEFAULT_LAYOUT;
}
if ("TIM".equals(operator) && regionMark.length() != 0) {
loader = CustomLayoutHelper.getInstance().getFromLauncherLayout(getContext(), widgetHost, mOpenHelper);
}
if (loader == null) {
final Partner partner = Partner.get(getContext().getPackageManager());
if (partner != null && partner.hasDefaultLayout()) {
final Resources partnerRes = partner.getResources();
int workspaceResId = partnerRes.getIdentifier(oppoDefaultLayout , "xml", partner.getPackageName());
if (workspaceResId <= 0) {
workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT , "xml", partner.getPackageName());
}
loader = new DefaultLayoutParser(getContext(), widgetHost, mOpenHelper, partnerRes, workspaceResId);
}
}
if ("RU".equals(regionMark) && regionMark.length() != 0) {
loader = null;
}
布局文件路径:vendor/partner_gms/apps/GmsSampleIntegration/res_dhs_full/partner_default_layout.xml Launcher3\go\res\xml\device_profiles.xml
make GmsSampleIntegrationGo 单编go布局 X:\nico\out\target\product\ums9230_nico\product\app\GmsSampleIntegration
Launcher:xml文件夹修改:device_profiles.xml default_workspace_5x5.xml
1)俄罗斯定制化 xml文件夹修改:default_workspace_5x5_RU.xml
InvariantDeviceProfile.java
private void initGrid(Context context, DefaultDisplay.Info displayInfo, DisplayOption displayOption) {
String regionMark = SystemProperties.get("ro.boot.regionmark", "");
if (regionMark.length() != 0 && "RU".equals(regionMark)){
defaultLayoutId = R.xml.default_workspace_5x5_RU;
}else {
defaultLayoutId = closestProfile.defaultLayoutId;
}
2)运营商定制:
Launcher:xml文件夹修改:vodafone_profiles.xml default_workspace_4x4.xml
InvariantDeviceProfile.java
static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
String COUNTRY_CODE = SystemProperties.get("ro.boot.regionmark", "");
String OPERATOR_TYPE = SystemProperties.get("ro.boot.operator", "");
int profile_id = 0;
if (COUNTRY_CODE.length() != 0 && "MX".equals(COUNTRY_CODE) && "TELCEL".equals(OPERATOR_TYPE)) {
profile_id = R.xml.telcel_profiles;
}else if (COUNTRY_CODE.length() != 0 && "EUEX".equals(COUNTRY_CODE) && "VODAFONE_EEA".equals(OPERATOR_TYPE)) {
profile_id = R.xml.vodafone_profiles;
}else {
profile_id = R.xml.device_profiles;
}
GmsSampleIntegration:/res_dhs_full/xml/partner_default_layout_EUEX_VODAFONE_EEA.xml (具体的布局界面)