Реализация перетаскивания с мультитач в Android - PullRequest
2 голосов
/ 12 марта 2012

Я ищу способ реализовать перетаскивание с помощью мультисенсорного ввода в моем приложении. У меня много представлений, и я хочу, чтобы первый пользователь перетаскивал представление одновременно с вторым пользователем, перетаскивая другое представление.

Мой метод перетаскивания одним касанием работает хорошо, вот часть моего кода (мои представления реализуют этот слушатель. 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 Ответ

2 голосов
/ 28 марта 2012

Я нашел решение и объяснение.

Android не поддерживает мультитач в нескольких видах, мультитач только для одного вида.Таким образом, чтобы получить мультисенсор для мульти-просмотра, нам нужно было отследить сенсорное событие в основной деятельности и создать новое событие для дочерних просмотров.

Спасибо Паскалю Уэлшу и его блогу (http://www.passsy.de/multitouch-for-all-views/), и модификацию ошибки в его коде, которую я нашел (http://code.google.com/p/friendbattle/issues/detail?id=19), я решил свою проблему.

Надеюсь, это поможет другим людям: -)

...