Laucher2 分析二 拖动原理

Launcher 中的拖动都是交个DragLayer 来实现的,DragLayer中有2个重要的接口 DragSource 和 DropTarget。
DragSource 为拖动对象的来源地,原始的Launcher中主要是指workspace,(还有文件夹也是Dragsource),
DropTarge 就是可以放置拖动对象的容器,WorkSpace,DeleteZone,UserFloder 都是DropTarget。

明确DragSource,DropTarget 这两个概念后,就比较容易理解拖动的原理了:

拖动的原理:  把拖动对象(显示为dragView,携带信息draginfo) ,从原来的对象容器(dragSource)中删除,然后 放入新的容器 (dropTarget)中。看上去很简单哈。那么代码中具体是如何实现的呢? 我简单描叙下:

在长按屏幕中的item后,在Launcher中启动进入拖动模式,touch的move事件传入 DragLayer 中,然后传入 DragController 中,

在启动函数 startDrag ( ) 中保存DragSource 和 Draginfo,然后在处理touch_move 事件的时候,处理拖动,在touch_up 事件中调用drop() 来放置拖动到View。

    private boolean drop(float x, float y) {
        final int[] coordinates = mCoordinatesTemp;
        DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);//找到目标容器

        if (dropTarget != null) {
            dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);// 这一步理解相对复杂点: 可以理解为把当前移动的对象从 目标容器 上空移除,为放置到容器内做准备。

            if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1],
                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo)) {//判断目标容器是否能可以放置当前的对象
                dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);//目标容器添加当前拖动的对象
                mDragSource.onDropCompleted((View) dropTarget, true);//来源容器调用完成拖动的处理
                return true;
            } else {
                mDragSource.onDropCompleted((View) dropTarget, false);
                return true;
            }
        }
        return false;
    }

具体到Workspace 中如何实现 OnDrop 和 onDropCompleted 就请查看源码吧。

猜你喜欢

转载自blog.csdn.net/xqt8888/article/details/7520287