【源码剖析】Launcher 8.0 源码 30---用户操作(7)拖拽模式之图标放到桌面上

本文详细剖析了Android Launcher 8.0中,用户如何将应用图标拖拽到桌面的过程。从onDragEnter、onDragOver到onDrop,逐一解释了每个阶段的工作原理,包括落脚点确认、动画效果、图标位置调整以及数据库更新等关键步骤。通过这些操作,理解了Launcher如何处理用户拖放操作并确保图标准确放置到桌面。
摘要由CSDN通过智能技术生成

讲解了各类特殊的操作,不能忘记最常见的操作,把图标放到桌面上。

workspace的droptarget,首先是onDragEnter,从folder或者buttonTargetBar进入workspace。比如先从workspace拖动到buttonTargetBar,然后再回到workspace里。最后回到workspace里面的时候,就会触发workspace的onDragEnter。其中有个方法setDropLayoutForDragObject。其细节是,从buttonTargetBar拖动回来,有可能是拖动到worksapce的边上会触发翻页的边上,这样就要求翻一页。

public void onDragEnter(DragObject d) {
    if (ENFORCE_DRAG_EVENT_ORDER) {
        enforceDragParity("onDragEnter", 1, 1);
    }
    mCreateUserFolderOnDrop = false;
    mAddToExistingFolderOnDrop = false;
    mDropToLayout = null;
    mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
    setDropLayoutForDragObject(d, mDragViewVisualCenter[0], mDragViewVisualCenter[1]);
}

 

在workspace里面拖动需要做的事情就多了:

public void onDragOver(DragObject d) {
    // Skip drag over events while we are dragging over side pages
    if (!transitionStateShouldAllowDrop()) return;
//首先是确认是否拖了明确的对象,检查iteminfo,因为后续的操作一定会用到item信息
    ItemInfo item = d.dragInfo;
    if (item == null) {
        if (ProviderConfig.IS_DOGFOOD_BUILD) {
            throw new NullPointerException("DragObject has null info");
        }
        return;
    }

  // 确认落脚点之前,先确认手指的位置,而后确定落脚点,在落脚点会有outline提示
    if (item.spanX < 0 || item.spanY < 0) throw new RuntimeException("Improper spans found");
    mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);

    final View child = (mDragInfo == null) ? null : mDragInfo.cell;
    if (setDropLayoutForDragObject(d, mDragViewVisualCenter[0], mDragViewVisualCenter[1])) {
        if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
            mSpringLoadedDragController.cancel();
        } else {
            mSpringLoadedDragController.setAlarm(mDragTargetLayout);
        }
    }

//还是确认落脚点,要分清楚是落在workspace还是hotseat
    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);
        }
//确认好落脚点之后,确认落脚需要的范围,一般是1x1。Widget则可能很大
        int minSpanX = item.spanX;
        int minSpanY = item.spanY;
        if (item.minSpanX > 0 && item.minSpanY > 0) {
            minSpanX = item.minSpanX;
            minSpanY = item.minSpanY;
        }
//寻找真实落脚点,有可能是没有落脚点的。比如将widget拖到hotseat上,但是hotseat不解释widget,此时算是没有落脚点。
        mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
                (int) mDragViewVisualCenter[1], minSpanX, minSpanY,
                mDragTargetLayout, mTargetCell);
        int reorderX = mTargetCell[0];
        int reorderY = mTargetCell[1];
        setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]);
        float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
                mDragViewVisualCenter

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值