在Android中使用多点触控实现拖放

时间:2012-03-12 18:26:22

标签: android drag-and-drop multi-touch

我正在寻找一种在我的应用程序中使用多点触控实现拖放的方法。 我有很多视图,我希望第一个用户在同一时间拖动视图而不是第二个用户拖动另一个视图。

我的单触式拖放效果很好,这是我的代码的一部分(我的视图正在实现这个监听器。onDragStart记录触摸的点,onDragContinuing改变视图的位置,onDrop检查位置是否有效):

public boolean onTouch(View v, MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        return onDragStart(event.getX(), event.getY());
    }

    else if (event.getAction() == MotionEvent.ACTION_MOVE){
        return onDragContinuing(event.getRawX(), event.getRawY());                      
    }

    else if (event.getAction() == MotionEvent.ACTION_UP){
        return onDrop(event.getRawX(), event.getRawY());
    }

    else{
        return false;
    }

}

我试图像这样实现多点触控,但它不起作用:

private static final int INVALID_POINTER_ID = -1;
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;

public boolean onTouch(View v, MotionEvent event) {

    int action = event.getAction();
    int actionCode = action & MotionEvent.ACTION_MASK;

    switch(actionCode){

        case MotionEvent.ACTION_DOWN :{
            Toast.makeText(getContext(), "down", Toast.LENGTH_SHORT).show();
            // Save the ID of this pointer
            mActivePointerId = event.getPointerId(0);
            return onDragStart(event.getX(), event.getY());
        }

        case MotionEvent.ACTION_POINTER_DOWN :{
            Toast.makeText(getContext(), "pointer down", Toast.LENGTH_SHORT).show();
            // Save the ID of this pointer
            // Extract the index of the pointer that left the touch sensor
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            mActivePointerId = event.getPointerId(pointerIndex);
            return onDragStart(event.getX(mActivePointerId), event.getY(mActivePointerId));
        }

        case MotionEvent.ACTION_MOVE :{
            Toast.makeText(getContext(), "move", Toast.LENGTH_SHORT).show();
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            final int mCurrentPointerId = event.getPointerId(pointerIndex);
            if (mActivePointerId == mCurrentPointerId){
                return onDragContinuing(getRawX(event, mActivePointerId), getRawY(event, mActivePointerId));
            }
            else return false;
        }

        case MotionEvent.ACTION_UP :{
            Toast.makeText(getContext(), "up", Toast.LENGTH_SHORT).show();
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            final int mCurrentPointerId = event.getPointerId(pointerIndex);

            if (mActivePointerId == mCurrentPointerId){
                return onDrop(event.getRawX(), event.getRawY());
            }
            else return false;

        }

        case MotionEvent.ACTION_POINTER_UP :{
            Toast.makeText(getContext(), "pointer up", Toast.LENGTH_SHORT).show();
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            final int mCurrentPointerId = event.getPointerId(pointerIndex);

            if (mActivePointerId == mCurrentPointerId){
                return onDrop(getRawX(event, pointerIndex), getRawY(event, pointerIndex));
            }
            else return false;

        }

        default :{
            return false;
        }

    }

}

/**
 * MotionEvent has no getRawX(int) method; simulate it pending future API approval. 
 */
private static float getRawX(MotionEvent event, int pointerIndex) {
    float offset = event.getX() - event.getRawX();
    return event.getX(pointerIndex) + offset;
}

/**
 * MotionEvent has no getRawY(int) method; simulate it pending future API approval. 
 */
private static float getRawY(MotionEvent event, int pointerIndex) {
    float offset = event.getY() - event.getRawY();
    return event.getY(pointerIndex) + offset;
}

怎么了?你能帮助我吗 ?谢谢你!

1 个答案:

答案 0 :(得分:2)

我找到了解决方案和解释。

Android在多视图中不支持多点触控,多点触控仅适用于一个视图。因此,要为多视图进行多点触控,我们必须在主要活动中捕获触摸事件并为子视图生成新事件。

感谢Pascal Welsch和他的博客(http://www.passsy.de/multitouch-for-all-views/),并修改了我发现的代码中的错误(http://code.google.com/p/friendbattle/issues/detail?id=19),我已经解决了我的问题。

希望这会对其他人有所帮助: - )