Как кодировать для мультитач
Поэтому я разрабатываю приложение, которое должно обрабатывать мультитач. В принципе, я хочу одно касание для поворота (это не проблема). И мультитач для прокрутки.
У меня есть основной код, но у меня возникают проблемы, когда происходит переход с одиночного на мультитач и наоборот. В основном движение будет толчковым, потому что среднее положение мультитача (два пальца) и абсолютное положение одного пальца находятся на расстоянии. Поэтому, если у меня два пальца на экране, они занимают срединное положение, а затем поднимают один палец, это будет похоже на быстрое перемещение из этого срединного положения в абсолютное положение одного пальца. Это будет движение, которое я не хочу.
Это мой код:
@Override
public boolean onTouchEvent( MotionEvent event ) {
float xEvent[] = new float[ 2 ];
float yEvent[] = new float[ 2 ];
switch( event.getPointerCount() ) {
case 1:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchRotate( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
case 2:
xEvent[ 0 ] = event.getX( 0 );
yEvent[ 0 ] = event.getY( 0 );
xEvent[ 1 ] = event.getX( 1 );
yEvent[ 1 ] = event.getY( 1 );
switch( event.getAction() ) {
case MotionEvent.ACTION_DOWN:
camera.onTouchDown( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_MOVE:
camera.onTouchSlide( ( ( xEvent[ 0 ] + xEvent[ 1 ] ) / 2 ), ( ( yEvent[ 0 ] + yEvent[ 1 ] ) / 2 ) );
return true;
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
return true;
case MotionEvent.ACTION_POINTER_2_UP:
camera.onTouchDown( xEvent[ 0 ], yEvent[ 0 ] );
return true;
default: return super.onTouchEvent( event );
}
default: return false;
}
}
Функция onTouchDown камеры просто устанавливает первое значение касания. Вот почему я также использую его в движении вверх, чтобы установить новое начальное значение для движения в одно касание при выходе из мультитача.
Я надеюсь, что кто-то знает, в чем моя проблема, и может помочь мне в дальнейшем.
2 ответа
Начните здесь, если вы еще не прочитали его, он затрагивает несколько вопросов, касающихся мультитач в Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
Несколько вещей о вашем размещенном коде:
- Вы никогда не увидите
ACTION_DOWN
со счетчиком указателей 2.ACTION_DOWN
отправляется только для первого указателя, который идет вниз. Все пальцы которые касаются экрана после первого отправятACTION_POINTER_DOWN
, - Не допускайте, чтобы касание касалось только двух пальцев, их может быть больше.
- Работать с маскированным действием намного проще (используйте
MotionEvent#getActionMasked()
), чем кодировать для каждого индекса указателя в отдельности. - В конце концов, индексы имеют значение только для извлечения данных из
MotionEvent
, Если вы отслеживаете движение указателя во времени, используйте идентификатор указателя. - Идентификаторы указателя - это просто числа. Не делайте предположений относительно того, какие значения они будут иметь, кроме того, что они будут целыми числами от 0 и выше.
Вы можете решить это с помощью простой математики, хотя, возможно, уже есть лучший способ.
Просто создайте объект, который удерживает позицию каждого пальца, когда происходит событие.ACTION_POINTER_X_UP, и логический объект, который содержит тип сенсорного режима, который вы в последний раз использовали.
case MotionEvent.ACTION_POINTER_1_UP:
camera.onTouchDown( xEvent[ 1 ], yEvent[ 1 ] );
boolean usedMultiTouch = true;
int x = event.getX(1);
int y = event.getY(1);
return true;
Затем ваш оператор ACTION_MOVE (внутри case=1) сработает, когда пользователь переместит свой палец, когда он перешел из режима multi в одно касание.
Теперь, в зависимости от того, что вы хотите сделать, вы можете либо игнорировать один ход (булево значение - ваша проверка), пока не сработает событие.ACTION_UP, и вы не установите логическое значение обратно в false
или же
Вы вызываете метод, который выполняет некоторые математические операции на основе сохраненных значений местоположения и пальца, который все еще находится на экране. Математика должна быть довольно простой, но я не знаю, что ты на самом деле хочешь делать.