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 就請查看源碼吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章