android Launcher 图标 加载/点击/拖动 的过程 2

handleMoveEvent我们上一篇已经说过了,endDrag()时拖动结束释放资源,我们单看drop(dragLayerX, dragLayerY)也就是

    private void drop(float x, float y) {
    
    
        final int[] coordinates = mCoordinatesTemp;
        final DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
 
        mDragObject.x = coordinates[0];
        mDragObject.y = coordinates[1];
        boolean accepted = false;
        if (dropTarget != null) {
    
    
            mDragObject.dragComplete = true;
            dropTarget.onDragExit(mDragObject);
            if (dropTarget.acceptDrop(mDragObject)) {
    
    
                dropTarget.onDrop(mDragObject);
                accepted = true;
            }
        }
        mDragObject.dragSource.onDropCompleted((View) dropTarget, mDragObject, accepted);
    }


也就是dropTarget.onDrop(mDragObject),其它内容不做详解,都是放松手后做了一些处理,我们只看看dropTarget.onDrop(mDragObject),DropTarget是个接口,在Workspace中实现

    public void onDrop(DragObject d) {
    
    
        mDragViewVisualCenter = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView,
                mDragViewVisualCenter);
 
        // We want the point to be mapped to the dragTarget.
        if (mDragTargetLayout != null) {
    
    
            if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
    
    
                mapPointFromSelfToSibling(mLauncher.getHotseat(), mDragViewVisualCenter);
            } else {
    
    
                mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null);
            }
        }
 
        CellLayout dropTargetLayout = mDragTargetLayout;
 
        int snapScreen = -1;
        if (d.dragSource != this) {
    
    
            final int[] touchXY = new int[] {
    
     (int) mDragViewVisualCenter[0],
                    (int) mDragViewVisualCenter[1] };
            onDropExternal(touchXY, d.dragInfo, dropTargetLayout, false, d);
        } else if (mDragInfo != null) {
    
    
            final View cell = mDragInfo.cell;
 
            if (dropTargetLayout != null) {
    
    
                // Move internally
                boolean hasMovedLayouts = (getParentCellLayoutForView(cell) != dropTargetLayout);
                boolean hasMovedIntoHotseat = mLauncher.isHotseatLayout(dropTargetLayout);
                long container = hasMovedIntoHotseat ?
                        LauncherSettings.Favorites.CONTAINER_HOTSEAT :
                        LauncherSettings.Favorites.CONTAINER_DESKTOP;
                int screen = (mTargetCell[0] < 0) ?
                        mDragInfo.screen : indexOfChild(dropTargetLayout);
                int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
                int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
                // First we find the cell nearest to point at which the item is
                // dropped, without any consideration to whether there is an item there.
                mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int)
                        mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
                // 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, false, d.dragView, null)) {
    
    
                    return;
                }
 
                if (addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell, d, false)) {
    
    
                    return;
                }
 
                // Aside from the special case where we're dropping a shortcut onto a shortcut,
                // we need to find the nearest cell location that is vacant
                mTargetCell = findNearestVacantArea((int) mDragViewVisualCenter[0],
                        (int) mDragViewVisualCenter[1], mDragInfo.spanX, mDragInfo.spanY, cell,
                        dropTargetLayout, mTargetCell);
 
                if (mCurrentPage != screen && !hasMovedIntoHotseat) {
    
    
                    snapScreen = screen;
                    snapToPage(screen);
                }
 
                if (mTargetCell[0] >= 0 && mTargetCell[1] >= 0) {
    
    
                    if (hasMovedLayouts) {
    
    
                        // Reparent the view
                        /* Modify 112809 Spreadst of 112809 Monkey start */
                        if(getParentCellLayoutForView(cell) != null){
    
    
                            getParentCellLayoutForView(cell).removeView(cell);
                        }else{
    
    
                            Log.d(TAG,"this view not be added to CellLayout");
                        }
                        addInScreen(cell, container, screen, mTargetCell[0], mTargetCell[1],
                                mDragInfo.spanX, mDragInfo.spanY);
                    }
 
                    // update the item's position after drop
                    final ItemInfo info = (ItemInfo) cell.getTag();
                    CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
                    dropTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
                    lp.cellX = mTargetCell[0];
                    lp.cellY = mTargetCell[1];
                    cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screen,
                            mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
 
                    if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
                            cell instanceof LauncherAppWidgetHostView) {
    
    
                        final CellLayout cellLayout = dropTargetLayout;
                        // We post this call so that the widget has a chance to be placed
                        // in its final location
 
                        final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
                        AppWidgetProviderInfo pinfo = hostView.getAppWidgetInfo();
                        if (pinfo != null && pinfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE) {
    
    
                            final Runnable resizeRunnable = new Runnable() {
    
    
                                public void run() {
    
    
                                    DragLayer dragLayer = mLauncher.getDragLayer();
                                    dragLayer.addResizeFrame(info, hostView, cellLayout);
                                }
                            };
                            post(new Runnable() {
    
    
                                public void run() {
    
    
                                    if (!isPageMoving()) {
    
    
                                        resizeRunnable.run();
                                    } else {
    
    
                                        mDelayedResizeRunnable = resizeRunnable;
                                    }
                                }
                            });
                        }
                    }
                    ItemInfo modelItem = null;
                    if(info != null) {
    
    
                        modelItem = LauncherModel.sItemsIdMap.get(info.id);
                    }
                    if(modelItem == null){
    
    
                        /**Bug141020 Bug146476 start.if the item has been deleted from db ,such as stk1 ,stk2,
                         *  just return,if the item is Folder and there is no other Shorcut except stk1 ,stk2 
                         *  delete the Emputy Folder**/
                        if(cell instanceof FolderIcon){
    
    
                            FolderIcon folder= (FolderIcon)cell;
                            ArrayList<View> folderItem = folder.mFolder.getItemsInReadingOrder();
                            if(folderItem.size() == 0){
    
    
                                getParentCellLayoutForView(cell).removeView(cell);
                            }
                        }
                        return;
                    }
                    LauncherModel.moveItemInDatabase(mLauncher, info, container, screen, lp.cellX,
                            lp.cellY);
                }
            }
 
            final CellLayout parent = (CellLayout) cell.getParent().getParent();
 
            // Prepare it to be animated into its new position
            // This must be called after the view has been re-parented
            final Runnable disableHardwareLayersRunnable = new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    mAnimatingViewIntoPlace = false;
                    updateChildrenLayersEnabled();
                }
            };
            mAnimatingViewIntoPlace = true;
            if (d.dragView.hasDrawn()) {
    
    
                int duration = snapScreen < 0 ? -1 : ADJACENT_SCREEN_DROP_DURATION;
                setFinalScrollForPageChange(snapScreen);
                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration,
                        disableHardwareLayersRunnable);
                resetFinalScrollForPageChange(snapScreen);
            } else {
    
    
                cell.setVisibility(VISIBLE);
            }
            parent.onDropChild(cell);
        }
    }


这个函数比较大,就不一一解释了,大概说一下,分为三种情况,第一如果是从主菜单拖到workspace待机的走onDropExternal(touchXY, d.dragInfo, dropTargetLayout, false, d)这里,如果是在workspace拖动的,分两种情况,一种就是没有把该图标拖到另外一页,就更新刷新就完了,如果拖到了下一页就走

addInScreen(cell, container, screen, mTargetCell[0], mTargetCell[1],mDragInfo.spanX, mDragInfo.spanY);


addInScreen也就是

    void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY,
            boolean insert) {
    
    
        if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
    
    
            if (screen < 0 || screen >= getChildCount()) {
    
    
                Log.e(TAG, "The screen must be >= 0 and < " + getChildCount()
                    + " (was " + screen + "); skipping child");
                return;
            }
        }
 
        final CellLayout layout;
        if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
    
    
            layout = mLauncher.getHotseat().getLayout();
            child.setOnKeyListener(null);
 
            // Hide folder title in the hotseat
            if (child instanceof FolderIcon) {
    
    
                ((FolderIcon) child).setTextVisible(false);
            }
 
            if (screen < 0) {
    
    
                screen = mLauncher.getHotseat().getOrderInHotseat(x, y);
            } else {
    
    
                // Note: We do this to ensure that the hotseat is always laid out in the orientation
                // of the hotseat in order regardless of which orientation they were added
                x = mLauncher.getHotseat().getCellXFromOrder(screen);
                y = mLauncher.getHotseat().getCellYFromOrder(screen);
            }
        } else {
    
    
            // Show folder title if not in the hotseat
            if (child instanceof FolderIcon) {
    
    
                ((FolderIcon) child).setTextVisible(true);
            }
 
            layout = (CellLayout) getChildAt(screen);
            child.setOnKeyListener(new IconKeyEventListener());
        }
 
        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
        if (lp == null) {
    
    
            lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
        } else {
    
    
            lp.cellX = x;
            lp.cellY = y;
            lp.cellHSpan = spanX;
            lp.cellVSpan = spanY;
        }
 
        if (spanX < 0 && spanY < 0) {
    
    
            lp.isLockedToGrid = false;
        }
 
        // Get the canonical child id to uniquely represent this view in this screen
        int childId = LauncherModel.getCellLayoutChildId(container, screen, x, y, spanX, spanY);
        boolean markCellsAsOccupied = !(child instanceof Folder);
        if (!layout.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) {
    
    
            // TODO: This branch occurs when the workspace is adding views
            // outside of the defined grid
            // maybe we should be deleting these items from the LauncherModel?
            Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout");
        }
 
        if (!(child instanceof Folder)) {
    
    
            child.setHapticFeedbackEnabled(false);
            child.setOnLongClickListener(mLongClickListener);
        }
        if (child instanceof DropTarget) {
    
    
            mDragController.addDropTarget((DropTarget) child);
        }
    }


这里做了一些计算,拖动的是什么,放在哪里等等吧,然后就layout.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)这里的layout是CellLayout所以layout.addViewToCellLayout也就是

    public boolean addViewToCellLayout(
            View child, int index, int childId, LayoutParams params, boolean markCells) {
    
    
        final LayoutParams lp = params;
 
        // Generate an id for each view, this assumes we have at most 256x256 cells
        // per workspace screen
        if (lp.cellX >= 0 && lp.cellX <= mCountX - 1 && lp.cellY >= 0 && lp.cellY <= mCountY - 1) {
    
    
            // If the horizontal or vertical span is set to -1, it is taken to
            // mean that it spans the extent of the CellLayout
            if (lp.cellHSpan < 0) lp.cellHSpan = mCountX;
            if (lp.cellVSpan < 0) lp.cellVSpan = mCountY;
 
            child.setId(childId);
 
            mChildren.addView(child, index, lp);
 
            if (markCells) markCellsAsOccupiedForView(child);
 
            return true;
        }
        return false;
    }


也就是mChildren.addView(child, index, lp)了,这里的mChildren也就是CellLayoutChildren,CellLayoutChildren我们前面说过了,就不再说了,至此一个移动过程结束。现在我们回过头来看看如果是从主菜单拖到workspace待机是怎么一个过程,这个过程主要是从主菜单到workspace的转换过程,我们还是从长按事件开始,从主菜单长按事件应该在AppsCustomizePagedView里面,但是这里没有,我们去它的父类PagedViewWithDraggableItems中寻找,也就是

    @Override
    public boolean onLongClick(View v) {
    
    
        // Return early if this is not initiated from a touch
        if (!v.isInTouchMode()) return false;
        // Return early if we are still animating the pages
        if (mNextPage != INVALID_PAGE) return false;
        // When we have exited all apps or are in transition, disregard long clicks
        if (!mLauncher.isAllAppsCustomizeOpen() ||
                mLauncher.getWorkspace().isSwitchingState()) return false;
 
        return beginDragging(v);
    }


也就是beginDragging,beginDragging在其子类AppsCustomizePagedView中重写了,也就是

    @Override
    protected boolean beginDragging(View v) {
    
    
        // Dismiss the cling
        mLauncher.dismissAllAppsCling(null);
 
        if (!super.beginDragging(v)) return false;
 
        // Go into spring loaded mode (must happen before we startDrag())
        mLauncher.enterSpringLoadedDragMode();
 
        if (v instanceof PagedViewIcon) {
    
    
            beginDraggingApplication(v);
        } else if (v instanceof PagedViewWidget) {
    
    
            beginDraggingWidget(v);
        }
        return true;
    }


mLauncher.enterSpringLoadedDragMode()是做什么的呢?就是隐藏主菜单,显示workspace待机,这样就从显示上切换到workspace了,但是实质还没切换到workspace,这个后面会讲到,然后就是区分开拖动的是PagedViewIcon(App图标),还是PagedViewWidget(widget图标)。这里我们只看App图标,也就是beginDraggingApplication(v)

    private void beginDraggingApplication(View v) {
    
    
        mLauncher.getWorkspace().onDragStartedWithItem(v);
        mLauncher.getWorkspace().beginDragShared(v, this);
    }


这里就是实质上切换到workspace了,先看上面一句mLauncher.getWorkspace().onDragStartedWithItem(v)也就是

    public void onDragStartedWithItem(View v) {
    
    
        final Canvas canvas = new Canvas();
 
        // We need to add extra padding to the bitmap to make room for the glow effect
        final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS;
 
        // The outline is used to visualize where the item will land if dropped
        mDragOutline = createDragOutline(v, canvas, bitmapPadding);
    }


这里同样创建了一个Bitmap为mDragOutline,和刚才我们讲解workspace拖动一样啦,就不再说了,然后看看下句mLauncher.getWorkspace().beginDragShared(v, this)也就是

    public void beginDragShared(View child, DragSource source) {
    
    
        Resources r = getResources();
 
        // We need to add extra padding to the bitmap to make room for the glow effect
        final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS;
 
        // The drag bitmap follows the touch point around on the screen
        final Bitmap b = createDragBitmap(child, new Canvas(), bitmapPadding);
 
        final int bmpWidth = b.getWidth();
 
        mLauncher.getDragLayer().getLocationInDragLayer(child, mTempXY);
        final int dragLayerX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2;
        int dragLayerY = mTempXY[1] - bitmapPadding / 2;
 
        Point dragVisualizeOffset = null;
        Rect dragRect = null;
        if (child instanceof BubbleTextView || child instanceof PagedViewIcon) {
    
    
            int iconSize = r.getDimensionPixelSize(R.dimen.app_icon_size);
            int iconPaddingTop = r.getDimensionPixelSize(R.dimen.app_icon_padding_top);
            int top = child.getPaddingTop();
            int left = (bmpWidth - iconSize) / 2;
            int right = left + iconSize;
            int bottom = top + iconSize;
            dragLayerY += top;
            // Note: The drag region is used to calculate drag layer offsets, but the
            // dragVisualizeOffset in addition to the dragRect (the size) to position the outline.
            dragVisualizeOffset = new Point(-bitmapPadding / 2, iconPaddingTop - bitmapPadding / 2);
            dragRect = new Rect(left, top, right, bottom);
        } else if (child instanceof FolderIcon) {
    
    
            int previewSize = r.getDimensionPixelSize(R.dimen.folder_preview_size);
            dragRect = new Rect(0, 0, child.getWidth(), previewSize);
        }
 
        // Clear the pressed state if necessary
        if (child instanceof BubbleTextView) {
    
    
            BubbleTextView icon = (BubbleTextView) child;
            icon.clearPressedOrFocusedBackground();
        }
 
        mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
                DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect);
        b.recycle();
    }


又到了这里了,这个和刚才workspace拖动是一样的了,也不做解释了,然后就进入mDragController.startDrag再然后就是handleMoveEvent循环了,然后就是拖到适当位置MotionEvent.ACTION_UP消息了,然后就是drop,dropTarget.onDrop这些过程和workspace拖动过程都一样了,唯独到了Workspace的onDrop中不同,也就是我们前面提到的,当从主菜单托出图标是会走onDropExternal(touchXY, d.dragInfo, dropTargetLayout, false, d)也就是

    private void onDropExternal(final int[] touchXY, final Object dragInfo,
            final CellLayout cellLayout, boolean insertAtFirst, DragObject d) {
    
    
        final Runnable exitSpringLoadedRunnable = new Runnable() {
    
    
            @Override
            public void run() {
    
    
                mLauncher.exitSpringLoadedDragModeDelayed(true, false);
            }
        };
 
        ItemInfo info = (ItemInfo) dragInfo;
        int spanX = info.spanX;
        int spanY = info.spanY;
        if (mDragInfo != null) {
    
    
            spanX = mDragInfo.spanX;
            spanY = mDragInfo.spanY;
        }
 
        final long container = mLauncher.isHotseatLayout(cellLayout) ?
                LauncherSettings.Favorites.CONTAINER_HOTSEAT :
                    LauncherSettings.Favorites.CONTAINER_DESKTOP;
        final int screen = indexOfChild(cellLayout);
        if (!mLauncher.isHotseatLayout(cellLayout) && screen != mCurrentPage
                && mState != State.SPRING_LOADED) {
    
    
            snapToPage(screen);
        }
 
        if (info instanceof PendingAddItemInfo) {
    
    
            final PendingAddItemInfo pendingInfo = (PendingAddItemInfo) dragInfo;
 
            boolean findNearestVacantCell = true;
            if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
    
    
                mTargetCell = findNearestArea((int) touchXY[0], (int) touchXY[1], spanX, spanY,
                        cellLayout, mTargetCell);
                if (willCreateUserFolder((ItemInfo) d.dragInfo, mDragTargetLayout, mTargetCell,
                        true) || willAddToExistingUserFolder((ItemInfo) d.dragInfo,
                                mDragTargetLayout, mTargetCell)) {
    
    
                    findNearestVacantCell = false;
                }
            }
            if (findNearestVacantCell) {
    
    
                    mTargetCell = findNearestVacantArea(touchXY[0], touchXY[1], spanX, spanY, null,
                        cellLayout, mTargetCell);
            }
 
            Runnable onAnimationCompleteRunnable = new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    // When dragging and dropping from customization tray, we deal with creating
                    // widgets/shortcuts/folders in a slightly different way
                    switch (pendingInfo.itemType) {
    
    
                    case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
                        mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) pendingInfo,
                                container, screen, mTargetCell, null);
                        break;
                    case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                        mLauncher.processShortcutFromDrop(pendingInfo.componentName,
                                container, screen, mTargetCell, null);
                        break;
                    default:
                        throw new IllegalStateException("Unknown item type: " +
                                pendingInfo.itemType);
                    }
                    cellLayout.onDragExit();
                }
            };
 
            // Now we animate the dragView, (ie. the widget or shortcut preview) into its final
            // location and size on the home screen.
            RectF r = estimateItemPosition(cellLayout, pendingInfo,
                    mTargetCell[0], mTargetCell[1], spanX, spanY);
            int loc[] = new int[2];
            loc[0] = (int) r.left;
            loc[1] = (int) r.top;
            setFinalTransitionTransform(cellLayout);
            float cellLayoutScale =
                    mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(cellLayout, loc);
            resetTransitionTransform(cellLayout);
 
            float dragViewScale =  Math.min(r.width() / d.dragView.getMeasuredWidth(),
                    r.height() / d.dragView.getMeasuredHeight());
            // The animation will scale the dragView about its center, so we need to center about
            // the final location.
            loc[0] -= (d.dragView.getMeasuredWidth() - cellLayoutScale * r.width()) / 2;
            loc[1] -= (d.dragView.getMeasuredHeight() - cellLayoutScale * r.height()) / 2;
 
            mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, loc,
                    dragViewScale * cellLayoutScale, onAnimationCompleteRunnable);
        } else {
    
    
            // This is for other drag/drop cases, like dragging from All Apps
            View view = null;
 
            switch (info.itemType) {
    
    
            case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                if (info.container == NO_ID && info instanceof ApplicationInfo) {
    
    
                    // Came from all apps -- make a copy
                    info = new ShortcutInfo((ApplicationInfo) info);
                }
                view = mLauncher.createShortcut(R.layout.application, cellLayout,
                        (ShortcutInfo) info);
                break;
            case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, cellLayout,
                        (FolderInfo) info, mIconCache);
                break;
            default:
                throw new IllegalStateException("Unknown item type: " + info.itemType);
            }
 
            // First we find the cell nearest to point at which the item is
            // dropped, without any consideration to whether there is an item there.
            if (touchXY != null) {
    
    
                mTargetCell = findNearestArea((int) touchXY[0], (int) touchXY[1], spanX, spanY,
                        cellLayout, mTargetCell);
                d.postAnimationRunnable = exitSpringLoadedRunnable;
                if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, true,
                        d.dragView, d.postAnimationRunnable)) {
    
    
                    return;
                }
                if (addToExistingFolderIfNecessary(view, cellLayout, mTargetCell, d, true)) {
    
    
                    return;
                }
            }
 
            if (touchXY != null) {
    
    
                // when dragging and dropping, just find the closest free spot
                mTargetCell = findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, null,
                        cellLayout, mTargetCell);
            } else {
    
    
                cellLayout.findCellForSpan(mTargetCell, 1, 1);
            }
            addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX,
                    info.spanY, insertAtFirst);
            cellLayout.onDropChild(view);
            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
            cellLayout.getChildrenLayout().measureChild(view);
 
            LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screen,
                    lp.cellX, lp.cellY);
 
            if (d.dragView != null) {
    
    
                // We wrap the animation call in the temporary set and reset of the current
                // cellLayout to its final transform -- this means we animate the drag view to
                // the correct final location.
                setFinalTransitionTransform(cellLayout);
                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, view,
                        exitSpringLoadedRunnable);
                resetTransitionTransform(cellLayout);
            }
        }
    }


这里也分为两个部分一部分是PendingAddItemInfo,PendingAddItemInfo是Widget有关的,这里不再详解,而我们的应用图标又会走到

addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX,info.spanY, insertAtFirst);


这里,addInScreen我们上面已经讲解过了,这里就不再赘述了。其它的内容不再讲解,有兴趣自己研究吧。至此我们的拖动过程就讲解完了。

    这两篇中我们讲解了Launcher图标的加载过程,点击图标进入应用的过程,拖动图标的过程,至于安装应用、卸载应用、更新应用、壁纸、widget等等其它Launcher内容,如果有需以后再讲解吧。


转载:https://blog.csdn.net/zhiyuan263287/article/details/19970937

猜你喜欢

转载自blog.csdn.net/gqg_guan/article/details/130890906
今日推荐