// The hotseat touch handling does not go through Workspace, and we always allow long press // on hotseat items. finalbooleaninHotseat= isHotseatLayout(v); if (!mDragController.isDragging()) { if (itemUnderLongClick == null) { // User long pressed on empty space mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); if (mWorkspace.isInOverviewMode()) { mWorkspace.startReordering(v); } else { showOverviewMode(true); } } else { ... mWorkspace.startDrag(longClickCellInfo); ... } } returntrue; }
public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY, DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion, float initialDragViewScale, boolean accessible) { ...
for (DragListener listener : mListeners) { listener.onDragStart(source, dragInfo, dragAction); }
...
mDragging = true; mIsAccessibleDrag = accessible;
mDragObject = newDropTarget.DragObject();
mDragObject.dragComplete = false; if (mIsAccessibleDrag) { // For an accessible drag, we assume the view is being dragged from the center. mDragObject.xOffset = b.getWidth() / 2; mDragObject.yOffset = b.getHeight() / 2; mDragObject.accessibleDrag = true; } else { mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft); mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop); }
@Override publicvoidonDragStart(final DragSource source, Object info, int dragAction) { mIsDragOccuring = true; updateChildrenLayersEnabled(false); mLauncher.lockScreenOrientation(); mLauncher.onInteractionBegin(); // Prevent any Un/InstallShortcutReceivers from updating the db while we are dragging InstallShortcutReceiver.enableInstallQueue();
if (mAddNewPageOnDrag) { mDeferRemoveExtraEmptyScreen = false; addExtraEmptyScreenOnDrag(); } }
主要是锁定屏幕,判断是否添加新的空白屏。
我们接着分析上面的代码,通过mDragObject = new DropTarget.DragObject()创建DragObject对象,储存相关的信息,然后生成DragView对象,通过dragView.show(mMotionDownX, mMotionDownY)方法将DragView对象添加到你手放置的位置,此时可以知道你拖拽的原来是DragView对象,最后调用handleMoveEvent(mMotionDownX, mMotionDownY)方法来处理位置移动,我们看一下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
privatevoidhandleMoveEvent(int x, int y) { mDragObject.dragView.move(x, y);
// Drop on someone? finalint[] coordinates = mCoordinatesTemp; DropTargetdropTarget= findDropTarget(x, y, coordinates); mDragObject.x = coordinates[0]; mDragObject.y = coordinates[1]; checkTouchMove(dropTarget);
// Check if we are hovering over the scroll areas mDistanceSinceScroll += Math.hypot(mLastTouch[0] - x, mLastTouch[1] - y); mLastTouch[0] = x; mLastTouch[1] = y; checkScrollState(x, y); }
finalViewchild= (mDragInfo == null) ? null : mDragInfo.cell; // Identify whether we have dragged over a side page if (workspaceInModalState()) {
//获取当前的CellLayout并处理 } else { //获取当前的CellLayout }
// Handle the drag over if (mDragTargetLayout != null) { // We want the point to be mapped to the dragTarget. if (mLauncher.isHotseatLayout(mDragTargetLayout)) { mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); } else { mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); }
// Otherwise, if we aren't adding to or creating a folder and there's no pending // reorder, then we schedule a reorder ReorderAlarmListenerlistener=newReorderAlarmListener(mDragViewVisualCenter, minSpanX, minSpanY, item.spanX, item.spanY, d.dragView, child); mReorderAlarm.setOnAlarmListener(listener); mReorderAlarm.setAlarm(REORDER_TIMEOUT); }
@Override publicvoidonDragEnter(DragObject d) { XLog.e(XLog.getTag(),XLog.TAG_GU); mPrevTargetRank = -1; mOnExitAlarm.cancelAlarm(); // Get the area offset such that the folder only closes if half the drag icon width // is outside the folder area mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset; }
switch (action) { case MotionEvent.ACTION_DOWN: ... handleMoveEvent(dragLayerX, dragLayerY); break; case MotionEvent.ACTION_MOVE: handleMoveEvent(dragLayerX, dragLayerY); break; case MotionEvent.ACTION_UP: // Ensure that we've processed a move event at the current pointer location. handleMoveEvent(dragLayerX, dragLayerY); mHandler.removeCallbacks(mScrollRunnable);
if (mDragging) { PointFvec= isFlingingToDelete(mDragObject.dragSource); if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) { vec = null; } if (vec != null) { dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec); } else { drop(dragLayerX, dragLayerY); } } endDrag(); break; case MotionEvent.ACTION_CANCEL: mHandler.removeCallbacks(mScrollRunnable); cancelDrag(); break; }
// We want the point to be mapped to the dragTarget. if (dropTargetLayout != null) { if (mLauncher.isHotseatLayout(dropTargetLayout)) { mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); } else { mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter, null); } }
// If the item being dropped is a shortcut and the nearest drop // cell also contains a shortcut, then create a folder with the two shortcuts. if (!mInScrollArea && createUserFolderIfNecessary(cell, container, dropTargetLayout, mTargetCell, distance, false, d.dragView, null)) { return; }
finalCellLayoutparent= (CellLayout) cell.getParent().getParent(); finalRunnablefinalResizeRunnable= resizeRunnable; // Prepare it to be animated into its new position // This must be called after the view has been re-parented finalRunnableonCompleteRunnable=newRunnable() { @Override publicvoidrun() { mAnimatingViewIntoPlace = false; updateChildrenLayersEnabled(false); if (finalResizeRunnable != null) { finalResizeRunnable.run(); } } }; mAnimatingViewIntoPlace = true; if (d.dragView.hasDrawn()) { // 绘制完成后的一些处理 ... } else { d.deferDragViewCleanupPostAnimation = false; cell.setVisibility(VISIBLE); } parent.onDropChild(cell); } }
// If the icon was dropped while the page was being scrolled, we need to compute // the target location again such that the icon is placed of the final page. if (!mContent.rankOnCurrentPage(mEmptyCellRank)) { // 再次排序 mTargetRank = getTargetRank(d, null);
// We only need to update the locations if it doesn't get handled in #onDropCompleted. if (d.dragSource != this) { updateItemLocationsInDatabaseBatch(); } mIsExternalDrag = false; } else { currentDragView = mCurrentDragView; // 如果来自文件夹则加入view并且排序 mContent.addViewForRank(currentDragView, si, mEmptyCellRank); }
privatebooleanbeginDragging(View v) { if (v instanceof WidgetCell) { if (!beginDraggingWidget((WidgetCell) v)) { returnfalse; } } else { Log.e(TAG, "Unexpected dragging view: " + v); }
// We don't enter spring-loaded mode if the drag has been cancelled if (mLauncher.getDragController().isDragging()) { // Go into spring loaded mode (must happen before we startDrag()) mLauncher.enterSpringLoadedDragMode(); }
public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY, DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion, float initialDragViewScale, boolean accessible) { ...