Launcher之图标拖拽事件学习——
仔细想想我们每次对手机上的一个图标(app)进行卸载、拖动换地儿、整理图标、归档到文件夹等是否感觉是很简单的操作呢?实则不然,其将通过一些列的判断来进行效果的达到,今天通过代码的学习来一步一步的查看,到底每一次都发生了什么以及如何处理
每一次对于图标的操作都是长按对不对?不信的话拿过你的手机尝试一下?没错吧? 那么我们就从长按的响应事件为入口进行代码剖析。
一、长按响应
<pre name="code" class="java"><pre name="code" class="java">public boolean onLongClick(View v)
<span style="white-space:pre"> </span>public boolean onLongClick(View v) {
<span style="white-space:pre"> </span>if (LauncherLog.DEBUG) {
<span style="white-space:pre"> </span>LauncherLog.d(TAG, "onLongClick: View = " + v + ", v.getTag() = " + v.getTag() + ", mState = " + mState);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (!isDraggingEnabled()) {//允许拖拽与否
<span style="white-space:pre"> </span>LauncherLog.d(TAG, "onLongClick: isDraggingEnabled() = " + isDraggingEnabled());
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (isWorkspaceLocked()) {//WorkSpace是否锁定
<span style="white-space:pre"> </span>LauncherLog.d(TAG, "onLongClick: isWorkspaceLocked() mWorkspaceLoading " + mWorkspaceLoading
<span style="white-space:pre"> </span>+ ", mWaitingForResult = " + mWaitingForResult);
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (mState != State.WORKSPACE){//是否处于WorkSpace状态
<span style="white-space:pre"> </span>LauncherLog.d(TAG, "onLongClick: mState != State.WORKSPACE: = " + mState);
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if (v instanceof Workspace) {
<span style="white-space:pre"> </span>LauncherLog.d(TAG, "v instanceof Workspace");
<span style="white-space:pre"> </span>if (!mWorkspace.isInOverviewMode()) {// 判断是否在缩略图模式下
<span style="white-space:pre"> </span>if (mWorkspace.enterOverviewMode()) {// 进入缩略图模式
<span style="white-space:pre"> </span>mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
<span style="white-space:pre"> </span>HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
<span style="white-space:pre"> </span>return true;
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>CellLayout.CellInfo longClickCellInfo = null;
<span style="white-space:pre"> </span>View itemUnderLongClick = null;
<span style="white-space:pre"> </span>if (v.getTag() instanceof ItemInfo) {// ItemInfo子类
<span style="white-space:pre"> </span>ItemInfo info = (ItemInfo) v.getTag();
<span style="white-space:pre"> </span>longClickCellInfo = new CellLayout.CellInfo(v, info);
<span style="white-space:pre"> </span>;
<span style="white-space:pre"> </span>itemUnderLongClick = longClickCellInfo.cell;
<span style="white-space:pre"> </span>resetAddInfo();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>// The hotseat touch handling does not go through Workspace, and we
<span style="white-space:pre"> </span>// always allow long press
<span style="white-space:pre"> </span>// on hotseat items.
<span style="white-space:pre"> </span>final boolean inHotseat = isHotseatLayout(v);// 是否热键栏
<span style="white-space:pre"> </span>boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();//是否允许长按处理
<span style="white-space:pre"> </span>if (allowLongPress && !mDragController.isDragging()) {// 允许长按 && 没有进行拖拽
<span style="white-space:pre"> </span>if (itemUnderLongClick == null) {// 如果itemUnderLongClick为null,进行长按空白处一样的处理
<span style="white-space:pre"> </span>// User long pressed on empty space
<span style="white-space:pre"> </span>mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
<span style="white-space:pre"> </span>HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
<span style="white-space:pre"> </span>if (mWorkspace.isInOverviewMode()) {
<span style="white-space:pre"> </span>mWorkspace.startReordering(v);
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>mWorkspace.enterOverviewMode();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(
<span style="white-space:pre"> </span>mHotseat.getOrderInHotseat(longClickCellInfo.cellX, longClickCellInfo.cellY));
<span style="white-space:pre"> </span> // 判断长按是否allapp按钮
<span style="white-space:pre"> </span>if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {// 长按的不是allapp按钮也不在文件夹展开的布局中
<span style="white-space:pre"> </span>/// M: Call the appropriate callback for the IMtkWidget on
<span style="white-space:pre"> </span>/// the current page
<span style="white-space:pre"> </span>/// when long click and begin to drag IMtkWidget.
<span style="white-space:pre"> </span>mWorkspace.startDragAppWidget(mWorkspace.getCurrentPage());
<span style="white-space:pre"> </span>// User long pressed on an item
<span style="white-space:pre"> </span>mWorkspace.startDrag(longClickCellInfo);// 开始拖拽
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return true;
<span style="white-space:pre"> </span>}
以上为对于长按事件的判断最后可以从代码中得出结论待到一切条件成立:
1、允许拖拽
isDraggingEnabled()
2、WorkSpace是否被锁定isWorkspaceLocked()
3、是否处于WorkSpace状态mState != State.WORKSPACE
4、当前长按的地方是否有Item如果没有判断是否处于缩略图模式如果在不处理假若不在进入缩略图模式
5、获取到CellInfo
6、判断是否为Hotseat,进而判断是否允许长按处理然后如果itemUnderLongClick为null,进行长按空白处一样的处理 ,即进入缩略图模式。
6、判断是否为Hotseat,进而判断是否允许长按处理然后如果itemUnderLongClick为null,进行长按空白处一样的处理 ,即进入缩略图模式。
7、判断长按的不是allapp按钮也不在文件夹展开的布局中
8、拖拽widget或者item
二、拖拽
void startDrag(CellLayout.CellInfo cellInfo)
void startDrag(CellLayout.CellInfo cellInfo) {
View child = cellInfo.cell;
if (LauncherLog.DEBUG_DRAG) {
LauncherLog.d(TAG, "startDrag cellInfo = " + cellInfo + ",child = " + child);
}
/// M: [ALPS01263567] Abnormal case, if user long press on all apps button and then
/// long press on