1.首先直觀感受什麼時候開始拖放?我們長按桌面一個應用圖標或者控件的時候拖放就開始了,包括在all app view中長按應用圖標,下面就是我截取的拖放開始的代碼調用堆棧
java代碼:
- at com.android.launcher2.DragController.startDrag
- at com.android.launcher2.Workspace.startDrag
- at com.android.launcher2.Launcher.onLongClick
- at android.view.View.performLongClick
- at android.widget.TextView.performLongClick
- at android.view.View$CheckForLongPress.run
- at android.os.Handler.handleCallback
- at android.os.Handler.dispatchMessage
- at android.os.Looper.loop
桌面應用圖標由Launcher.onLongClick負責監聽處理,插入斷點debug進入onLongclick函數
java代碼:
- if (!(v instanceof CellLayout)) {
- v = (View) v.getParent();
- }
- //獲取桌面CellLayout上一個被拖動的對象
- CellLayout.CellInfo cellInfo = (CellLayout.CellInfo) v.getTag();
- if (mWorkspace.allowLongPress()) {
- if (cellInfo.cell == null) {
- } else {
- if (!(cellInfo.cell instanceof Folder)) {
- //調用Workspace.startDrag處理拖動
- mWorkspace.startDrag(cellInfo);
- }
- }
- }
我上面只寫出關鍵代碼,首先是獲取被拖動的對象v.getTag(),Tag什麼時候被設置進去的了
java代碼:
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (action == MotionEvent.ACTION_DOWN) {
- boolean found = false;
- for (int i = count - 1; i >= 0; i--) {
- final View child = getChildAt(i);
- if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) {
- child.getHitRect(frame);
- //判斷區域是否在這個子控件的區間,如果有把child信息賦給mCellInfo
- if (frame.contains(x, y)) {
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- cellInfo.cell = child;
- cellInfo.cellX = lp.cellX;
- cellInfo.cellY = lp.cellY;
- cellInfo.spanX = lp.cellHSpan;
- cellInfo.spanY = lp.cellVSpan;
- cellInfo.valid = true;
- found = true;
- mDirtyTag = false;
- break;
- }
- }
- }
- mLastDownOnOccupiedCell = found;
- if (!found) {
- //沒有child view 說明沒有點擊桌面圖標項
- cellInfo.cell = null;
- }
- setTag(cellInfo);
- }