Мультитач для Android – второй палец ACTION.MOVE игнорируется

Следующий код — это то, что я пытался использовать для мультитач. Первый палец установлен правильно и перемещается, когда я провожу пальцем. Второй палец появляется и исчезает, когда я касаюсь и отпускаю палец, но он никогда не двигается. Есть идеи, что случилось?

Я прочитал блог разработчиков. понять в чем проблемы.

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction() & MotionEvent.ACTION_MASK;
        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        int pointerId = event.getPointerId(pointerIndex);
        switch (action) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            if (pointerId == 0)
            {
                fingerOneDown = 1;
                fingerOneX = event.getX(pointerIndex);
                fingerOneY = event.getY(pointerIndex);
            }
            if (pointerId == 1)
            {
                fingerTwoDown = 1;
                fingerTwoX = event.getX(pointerIndex);
                fingerTwoY = event.getY(pointerIndex);
            }
            break;

        case MotionEvent.ACTION_UP:          
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL:
            if (pointerId == 0)
            {
                fingerOneDown = 0;
                fingerOneX = event.getX(pointerIndex);
                fingerOneY = event.getY(pointerIndex);
            }
            if (pointerId == 1)
            {
                fingerTwoDown = 0;
                fingerTwoX = event.getX(pointerIndex);
                fingerTwoY = event.getY(pointerIndex);
            }
            break;

        case MotionEvent.ACTION_MOVE:
            if (pointerId == 0)
            {
                fingerOneDown = 1;
                fingerOneX = event.getX(pointerIndex);
                fingerOneY = event.getY(pointerIndex);
            }
            if (pointerId == 1)
            {
                fingerTwoDown = 1;
                fingerTwoX = event.getX(pointerIndex);
                fingerTwoY = event.getY(pointerIndex);
            }

            break;
        }
        return true;
    }

person Nathan Tornquist    schedule 27.01.2012    source источник


Ответы (1)


Неважно это. Я починил это. Событие ACTION.MOVE всегда получает ноль в качестве pointerId по какой-то странной причине. Из-за этого вам всегда нужно пересчитывать pointerId внутри события, как показано ниже:

       case MotionEvent.ACTION_MOVE:

        int pointerCount = event.getPointerCount();
        for(int i = 0; i < pointerCount; ++i)
        {
            pointerIndex = i;
            pointerId = event.getPointerId(pointerIndex);
            Log.d("pointer id - move",Integer.toString(pointerId));
            if(pointerId == 0)
            {
                fingerOneDown = 1;
                fingerOneX = event.getX(pointerIndex);
                fingerOneY = event.getY(pointerIndex);
            }
            if(pointerId == 1)
            {
                fingerTwoDown = 1;
                fingerTwoX = event.getX(pointerIndex);
                fingerTwoY = event.getY(pointerIndex);
            }
        }
        break;
person Nathan Tornquist    schedule 08.06.2012
comment
Это ошибка? У меня такое же странное поведение. Я искал в Google, и у некоторых других людей это тоже было. - person C.d.; 03.07.2013
comment
Я не знаю, является ли это ошибкой, но это задокументированная проблема, и итерация по указателям решает ее. Во всяком случае, это может быть просто странное дизайнерское решение. - person Nathan Tornquist; 03.07.2013
comment
Только что столкнулся с этим, и я должен сказать, что это довольно логично. POINTER DOWN/UP — это простое событие, которое может запускаться как отдельные события. Однако MOVE относится к каждому указателю. Разделение движения указателя на разные события сделало бы вещи довольно сложными и, возможно, даже невозможными (различение между смахиванием несколькими указателями и смахиванием одним пальцем при удерживании второго указателя в одном месте). Таким образом, индекс действия не имеет смысла для MOVE, и вам нужно вручную проверять движение указателя с помощью итерации (как вы показали) и сохраненной истории (чтобы проверить, какой из них переместился). - person Pavel Horal; 28.03.2014
comment
Чтобы определить, какой указатель переместился, вы можете использовать MotionEvent.getHistoricalX(). Код с r3dux.org: if ( (int)event.getX(i) != (int)event.getHistoricalX(i,0) || (int)event.getY(i) != (int)event.getHistoricalY( я, 0)) - person Zach; 12.05.2017