伪3D Touch在Android7.1系统上首次推出,只有Shortcut项,在Android8.0上又增加了Notification和System Shortcut两项。由于开发需要,基于Android8.0 Launcher3代码进行分析,并有了这篇文档。如有错误之处,欢迎指出!
3D Touch
Android的伪3D Touch效果如下图所示。3D Touch是一种立体触控技术,被苹果称为新一代多点触控技术,屏幕可感应不同的感压力度触控。为什么说Android上的是伪3D Touch呢?因为在Launcher3上的实现是通过长按屏幕触发弹出菜单的,并不是以压力传感器为触发点的。
Android实现的伪3D Touch弹出框中实现中有三种类型:System Shorcut、Shortcut、notification,分别如下图所示。System Shortcut包含小部件和应用信息两项;Shortcut则是应用深度定制的快捷方式,可以拖动到桌面;Notification则是通知栏上的通知,可以在弹出框上左右滑动直接删除Notification。当有Notification时,Shortcut最多显示两项,没有Notification时,最多显示4项。
代码实现分析
Android的伪3D Touch功能的实现是嵌入到原来的桌面拖拽框架中的,由长按应用图标触发启动,桌面(Workspace)长按事件的处理入口放在了Launcher类中,抽屉长按事件的处理入口则在AllAppsContainerView类中,文件夹则在Folder类中。长按应用图标的处理都会调用到Workspace.beginDragShared()函数来启动拖拽流程,故这里只分析从Workspace长按应用图标的实现,另外的两种启动类似,其启动流程时序图如下所示。
下面从长按事件回调开始详细描述代码实现。当长按的View是应用图标时会执行下面所写Launcher类的代码块,调用Workspace类的startDrag()方法,其中CellInfo记录了应用图标对应的App包括图标位置、包名、等信息,DragOptions是新增加的控制类,主要是用于拖拽过程中与伪3D Touch功能进行交互。接着调用beginDragShared()函数,参数child即点击的应用图标view。关键代码如下:
/**com.android.launcher3.Launcher*/
public boolean onLongClick(View v) {
......
} else {
final boolean isAllAppsButton =
!FeatureFlags.NO_ALL_APPS_ICON && isHotseatLayout(v) &&
mDeviceProfile.inv.isAllAppsButtonRank(mHotseat.getOrderInHotseat(
longClickCellInfo.cellX, longClickCellInfo.cellY));
if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {
// User long pressed on an item
mWorkspace.startDrag(longClickCellInfo, new DragOptions());
}
}
}
return