3. ITEM_LIVE_FOLDER,文件夹
–UserFolderInfo 对应实现布局文件R.layout.folder_icon
–LiveFolderInfo 对应实现布局文件R.layout.live_folder_icon
4. ITEM_WALLPAPER,墙纸。
下面,我们详细的来说一下launcher里面的详细功能:
1.DragLayer–DragLayer继承FrameLayout,并在此基础上组合了DragController实现拖放功能,DragLayer主要监听下面两个用户事件onInterceptTouchEvent和onTouchEvent
并交给DragController进行处理,DragController根据是否在拖放中等信息控制控件拖放过程处理。DragLayer 是Launcher这个activity的顶层view,其实在Launcher2这个应用只有Laucher.java这么一个activity。
2.DeleteZone–
[html] view plain copy
-
<com.android.launcher2.DeleteZone
-
android:id=“@+id/delete_zone”
-
android:layout_width=“@dimen/delete_zone_size”
-
android:layout_height=“@dimen/delete_zone_size”
-
android:paddingTop=“@dimen/delete_zone_padding”
-
android:layout_gravity=“bottom|center_horizontal”
-
android:scaleType=“center”
-
android:src=“@drawable/delete_zone_selector”
-
android:visibility=“invisible”
-
launcher:direction=“horizontal”
-
/>
在launcher.xml中,可以发现,DeleteZone默认是不显示的android:visibility=“invisible”,但是我们每次开始拖放图标的时候DeleteZone就显示了,这个功能是如何实现的呢?在代码中可以发现DeleteZone实现了DragController.DragListener接口,
[html] view plain copy
- public class DeleteZone extends ImageView implements DropTarget, DragController.DragListener
DragListener提供两个接口方法,
onDragStart:隐藏把手,显示DeleteZone
onDragEnd:显示把手,隐藏DeleteZone
在DeleteZone中,看一下代码:
[java] view plain copy
-
public void onDragStart(DragSource source, Object info, int dragAction) {
-
final ItemInfo item = (ItemInfo) info;
-
if (item != null) {
-
mTrashMode = true;
-
createAnimations();
-
final int[] location = mLocation;
-
getLocationOnScreen(location);
-
mRegion.set(location[0], location[1], location[0] + mRight - mLeft,
-
location[1] + mBottom - mTop);
-
mDragController.setDeleteRegion(mRegion);
-
mTransition.resetTransition();
-
startAnimation(mInAnimation);
-
mHandle.startAnimation(mHandleOutAnimation);
-
setVisibility(VISIBLE);
-
}
-
}
-
public void onDragEnd() {
-
if (mTrashMode) {
-
mTrashMode = false;
-
mDragController.setDeleteRegion(null);
-
startAnimation(mOutAnimation);
-
mHandle.startAnimation(mHandleInAnimation);
-
setVisibility(GONE);
-
}
-
}
分别在开始DragController开始拖放和结束拖放的时候被调用.
另外DeleteZone实现了DropTarget接口的onDrop方法
[java] view plain copy
-
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
-
DragView dragView, Object dragInfo) {
-
final ItemInfo item = (ItemInfo) dragInfo;
-
if (item.container == -1) return;
-
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-
if (item instanceof LauncherAppWidgetInfo) {
-
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
-
}
-
} else {
-
if (source instanceof UserFolder) {
-
final UserFolder userFolder = (UserFolder) source;
-
final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
-
// Item must be a ShortcutInfo otherwise it couldn’t have been in the folder
-
// in the first place.
-
userFolderInfo.remove((ShortcutInfo)item);
-
}
-
}
-
if (item instanceof UserFolderInfo) {
-
final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
-
LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
-
mLauncher.removeFolder(userFolderInfo);
-
} else if (item instanceof LauncherAppWidgetInfo) {
-
final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
-
final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
-
if (appWidgetHost != null) {
-
final int appWidgetId = launcherAppWidgetInfo.appWidgetId;
-
// Deleting an app widget ID is a void call but writes to disk before returning
-
// to the caller…
-
new Thread(“deleteAppWidgetId”) {
-
public void run() {
-
appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
-
}
-
}.start();
-
}
-
}
-
LauncherModel.deleteItemFromDatabase(mLauncher, item);
-
}
当把图标拖放到DeleteZone,就会调用DeleteZone,实现的onDrop方法对应用图标进行删除处理。
3.屏幕左右移动按钮,就是使用的ImageView,
[html] view plain copy
-
<ImageView
-
android:id=“@+id/previous_screen”
-
android:layout_width=“93dip”
-
android:layout_height=“@dimen/button_bar_height”
-
android:layout_gravity=“bottom|left”
-
android:layout_marginLeft=“6dip”
-
android:scaleType=“center”
-
android:src=“@drawable/home_arrows_left”
-
android:onClick=“previousScreen”
-
android:focusable=“true”
-
android:clickable=“true” />
-
<ImageView
-
android:id=“@+id/next_screen”
-
android:layout_width=“93dip”
-
android:layout_height=“@dimen/button_bar_height”
-
android:layout_gravity=“bottom|right”
-
android:layout_marginRight=“6dip”
-
android:scaleType=“center”
-
android:src=“@drawable/home_arrows_right”
-
android:onClick=“nextScreen”
-
android:focusable=“true”
-
android:clickable=“true” />
注意三点,
–1.桌面左右移动时Drawable的变换,变换图标列表可查看home_arrows_right.xml
,ImageView通过把drawable传递给worksapce,当桌面切换时通过调用Drawable.setLevel()方法实现不同图标显示。
–2.当点击实现左右桌面切换,查看上面的布局文件中android:onClick=“previousScreen”,该属性定义了一个 onClick事件响应函数,在Launcher.java中的788行。
[html] view plain copy
-
@SuppressWarnings({“UnusedDeclaration”})
-
publicvoid previousScreen(View v) {
-
if(!isAllAppsVisible()) {
-
mWorkspace.scrollLeft();
-
}
-
}
–3.在(Launcher.setupViews)中添加了长按事件OnLongClickListener有当长按会执行launcher.onlongclick方法,方法执行显示5个桌面的预览微缩图显示。
4.RelativeLayout–android:id=“@+id/all_apps_button_cluster”,如前面截图右边灰色竖状条,它是一个相对布局对象,上面承载了三个view
中间是一个HandleView,是一个进入allappview的按钮,HandleView的左面是拨号,右面是浏览器两个ImageView。
–HandleView
–1.点击事件 传递给Launcher.onClick进行处理 显示应用菜单view
–2.长按事件 传递给Launcher.onLongClick进行处理,方法执行显示5个桌面的预览微缩图显示
–拨号或者浏览器
–onClick响应:android:onClick=“launchHotSeat”
5.Workspace–用户桌面包括5个workspace_screen,launcher:defaultScreen="2"在前面已经说过,表示默认桌面是第三个。
workspace继承了viewgroup,5个workspace_screen作为它的child,值得注意它只接收CellLayout类型的child,workspace重写了addview函数,添加了非CellLayout的child将抛异常
–Workspace长按事件由launcher.onLongClick来监听
–Workspace实现了DropTarget, DragSource两个接口,意味着Workspace既是拖放源,又是拖放目的地
–Workspace实现DragScroller接口,DragScroller接口提供两个方法
void scrollLeft()和void scrollRight()在拖放过程被DragController调用实现桌面的左右滚动。
–CellLayout Workspace下的一个桌面布局,CellLayout也是ViewGroup的子类,
Workspace下有5个CellLayout顺序排列,Workspace下布局文件:android:scrollbars="horizontal"决定了5个CellLayout排列是横向还是纵向的
[html] view plain copy
-
<com.android.launcher2.CellLayout
-
xmlns:android=“http://schemas.android.com/apk/res/android”
-
xmlns:launcher=“http://schemas.android.com/apk/res/com.android.launcher”
-
android:layout_width=“match_parent”
-
android:layout_height=“match_parent”
-
android:hapticFeedbackEnabled=“false”
-
launcher:cellHeight=“@dimen/workspace_cell_height”//每个cell的高度
-
launcher:longAxisStartPadding=“8dip”//cell距离父view CellLayout左边距
-
launcher:longAxisEndPadding=“78dip”//cell距离父view CellLayout右边距
-
launcher:shortAxisStartPadding=“0dip”//cell距离父view CellLayout上边距
-
launcher:shortAxisEndPadding=“0dip”//cell距离父view CellLayout下边距
-
launcher:shortAxisCells=“4”//CellLayout cells行数
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
[外链图片转存中…(img-tTdvifDe-1711866294917)]
【Android高级架构视频学习资源】