Android launcher3 -- launcher3源码1
Android launcher3 – launcher3源码1
Launcher3(J 泡在网上的日子)
launcher3源码
Launcher3源码分析系列
下载launcher3源码
使用Android Studio运行
|
默认布局读取
Android launcher – launcher源码修改 2简单提及
xml布局文件
一般该文件命中都包含default_workspace字符串,只需要查一下
default_workspace_XxY.xml 桌面默认布局文件,
dw_phone_hotseat.xml 手机hotseat布局(即底部DOCK区)
dw_tablet_hotseat.xml 平板hotseat布局
dw_phone_hotseat.xml
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
<!-- Dialer, Messaging, [All Apps], Browser, Camera -->
<resolve
launcher:container="-101"
launcher:screen="0"
launcher:x="0"
launcher:y="0" >
<favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
<favorite launcher:uri="tel:123" />
<favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
</resolve>
<resolve
launcher:container="-101"
launcher:screen="1"
launcher:x="1"
launcher:y="0" >
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
<favorite launcher:uri="sms:" />
<favorite launcher:uri="smsto:" />
<favorite launcher:uri="mms:" />
<favorite launcher:uri="mmsto:" />
</resolve>
<!-- All Apps -->
<resolve
launcher:container="-101"
launcher:screen="3"
launcher:x="3"
launcher:y="0" >
<favorite
launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
<favorite launcher:uri="http://www.example.com/" />
</resolve>
<resolve
launcher:container="-101"
launcher:screen="4"
launcher:x="4"
launcher:y="0" >
<favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
<favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
</resolve>
</favorites>
default_workspace_4x4.xml
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<!-- Hotseat -->
<include launcher:workspace="@xml/dw_phone_hotseat" />
<!-- Bottom row -->
<resolve
launcher:screen="0"
launcher:x="0"
launcher:y="3" >
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
<favorite launcher:uri="mailto:" />
</resolve>
<resolve
launcher:screen="0"
launcher:x="1"
launcher:y="3" >
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
<favorite launcher:uri="#Intent;type=images/*;end" />
</resolve>
<resolve
launcher:screen="0"
launcher:x="3"
launcher:y="3" >
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
<favorite launcher:uri="market://details?id=com.android.launcher" />
</resolve>
</favorites>
favorites中可用添加自定义:添加第一个相机,可重复创建;第二个日历
<resolve
launcher:screen="0"
launcher:x="2"
launcher:y="3">
<favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
<favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
</resolve>
<resolve
launcher:screen="0"
launcher:x="0"
launcher:y="0">
<favorite
launcher:className="com.android.calendar.AllInOneActivity"
launcher:packageName="com.android.calendar" />
</resolve>
xml布局文件读取
从Find in Path搜索的中代码中调用
InvariantDeviceProfile.java中
ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() {
ArrayList<InvariantDeviceProfile> predefinedDeviceProfiles = new ArrayList<>();
// width, height, #rows, #columns, #folder rows, #folder columns,
// iconSize, iconTextSize, #hotseat, #hotseatIconSize, defaultLayoutId.
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Super Short Stubby",
255, 300, 2, 3, 2, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Shorter Stubby",
255, 400, 3, 3, 3, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Short Stubby",
275, 420, 3, 4, 3, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Stubby",
255, 450, 3, 4, 3, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus S",
296, 491.33f, 4, 4, 4, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4",
335, 567, 4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5",
359, 567, 4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Large Phone",
406, 694, 5, 5, 4, 4, 4, 64, 14.4f, 5, 56, R.xml.default_workspace_5x5));
// The tablet profile is odd in that the landscape orientation
// also includes the nav bar on the side
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 7",
575, 904, 5, 6, 4, 5, 4, 72, 14.4f, 7, 60, R.xml.default_workspace_5x6));
// Larger tablet profiles always have system bars on the top & bottom
predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 10",
727, 1207, 5, 6, 4, 5, 4, 76, 14.4f, 7, 64, R.xml.default_workspace_5x6));
predefinedDeviceProfiles.add(new InvariantDeviceProfile("20-inch Tablet",
1527, 2527, 7, 7, 6, 6, 4, 100, 20, 7, 72, R.xml.default_workspace_4x4));
return predefinedDeviceProfiles;
}
从getPredefinedDeviceProfiles()逆向索冀
Launcher.java:
@Override
protected void onCreate(Bundle savedInstanceState)
LauncherAppState.setApplicationContext(getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
mModel.startLoader(mWorkspace.getRestorePage());
LauncherModel.java:异步线程LoaderTas加载图标
public void startLoader(int synchronousBindPage, int loadFlags)
mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags);
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
sWorker.post(mLoaderTask);private class LoaderTask implements Runnable
public void run()
loadAndBindWorkspace()
loadAndBindAllApps();loadAndBindWorkspace()
loadWorkspace()
bindWorkspace(-1);loadAndBindAllApps()
loadAllApps();
updateIconCache();
LauncherProvider.java:
@Override
public boolean onCreate()
LauncherAppState.setLauncherProvider(this);/**
* Loads the default workspace based on the following priority scheme:
* 1) From the app restrictions
* 2) From a package provided by play store
* 3) From a partner configuration APK, already in the system image
* 4) The default configuration for the particular device
*/
synchronized public void loadDefaultFavoritesIfNecessary()
AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction();
loader = getDefaultLayoutParser();
if ((mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader) <= 0) && usingExternallyProvidedLayout)
mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), getDefaultLayoutParser());@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction()
return AutoInstallsLayout.get(ctx, packageName, targetResources, mOpenHelper.mAppWidgetHost, mOpenHelper);private DefaultLayoutParser getDefaultLayoutParser()
private DefaultLayoutParser getDefaultLayoutParser() { int defaultLayout = LauncherAppState.getInstance() .getInvariantDeviceProfile().defaultLayoutId; return new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost, mOpenHelper, getContext().getResources(), defaultLayout); }
LauncherAppState.java:
private LauncherAppState() //单例模式
mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);public InvariantDeviceProfile getInvariantDeviceProfile()
return mInvariantDeviceProfile;
InvariantDeviceProfile.java:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
InvariantDeviceProfile(Context context)
ArrayList closestProfiles = findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles());getPredefinedDeviceProfiles()
predefinedDeviceProfiles.add(new InvariantDeviceProfile(“Super Short Stubby”, 255, 300, 2, 3, 2, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, int maapc, float is, float its, float hs, float his, int dlId)
defaultLayoutId = dlId;
Launcher3基本结构图
相关布局参数
defaultLayoutId :默认布局ID
numRows \numColumns :workspace行列
numHotseatIcons :DOCK区个数
hotseatAllAppsRank :DOCK区中间AllApps图标位置
numFolderRows \numFolderColumns :文件夹行列数
iconSize :图标大小
iconTextSize :workspace图标下文字大小
hotseatIconSize :DOCK区图标大小config_workspaceDefaultScreen:默认主屏在launcher.xml布局中
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
InvariantDeviceProfile(Context context) {
//。。。。。。省略
ArrayList<InvariantDeviceProfile> closestProfiles =
findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles());
InvariantDeviceProfile interpolatedDeviceProfileOut =
invDistWeightedInterpolate(minWidthDps, minHeightDps, closestProfiles);
InvariantDeviceProfile closestProfile = closestProfiles.get(0);
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
numHotseatIcons = closestProfile.numHotseatIcons;
hotseatAllAppsRank = (int) (numHotseatIcons / 2);
defaultLayoutId = closestProfile.defaultLayoutId;
numFolderRows = closestProfile.numFolderRows;
numFolderColumns = closestProfile.numFolderColumns;
minAllAppsPredictionColumns = closestProfile.minAllAppsPredictionColumns;
iconSize = interpolatedDeviceProfileOut.iconSize;
iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
//。。。。。。省略
}
上一篇: 屏占比更高视野更广 高关注全面屏手机推荐
推荐阅读
-
Android开发实现Launcher3应用列表修改透明背景的方法
-
Android开发中Launcher3常见默认配置修改方法总结
-
【Android】用Cubism 2制作自己的Live2D——官方App样例源码学习(1)!
-
android 9.0 Launcher3 去掉抽屉式,显示所有 app
-
Android8.1 Launcher3 去掉抽屉方法
-
Android消息机制系列(1)——Handler Looper Message源码解析
-
android Launcher3删除风格
-
android Launcher3 设置默认桌面应用
-
Android launcher3 循环桌面
-
android10.0(Q) Launcher3 去掉抽屉