2010-11-19 3 views
8

Так что я разрабатываю приложение, которое должно обрабатывать мультитач. В принципе, я хочу одно касание для вращения (это не проблема). И мультитач для прокрутки.Как закодировать для multitouch

У меня есть базовый код, но у меня возникают проблемы при переходе от одного к мультитач и вице-верки. В основном движение будет толчком, потому что медианное положение мультитач (два пальца) и абсолютное положение одного пальца находятся на расстоянии. Поэтому, если у меня есть два пальца на экране, они составляют медианное положение, а затем поднимают один палец, это будет похоже на быстрое перемещение из этого медианного положения в абсолютное положение одного пальца. Это будет движение, которого я не хочу.

Это мой код:

@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 камеры просто устанавливает первое значение сенсорного движения. Вот почему я также использую его в движении вверх, чтобы установить новое значение начала для движения с одним касанием при выходе из мультитач.

Я надеюсь, что кто-то знает, в чем моя проблема, и может помочь мне дальше.

ответ

10

Начала здесь, если вы не читали ее уже, она идет через ряд вещей, связанные с мультитач в Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

Несколько вещей о вашем публикуемом коде:

  1. Вы будете никогда не см. ACTION_DOWN с указанием указателя 2. ACTION_DOWN отправляется только для первого указателя, который идет вниз. Все пальцы, которые касаются экрана после первого, отправят ACTION_POINTER_DOWN.
  2. Не допускайте, чтобы до 2 пальцев касалось пальца, там может быть и больше.
  3. Гораздо проще работать с замаскированным действием (используйте MotionEvent#getActionMasked()), чем для каждого индекса указателя.
  4. В конце концов, индексы имеют значение только для вытаскивания данных из MotionEvent. Если вы отслеживаете движение указателя со временем, используйте идентификатор указателя.
  5. Идентификаторы указателей - это просто цифры. Не делайте предположений о том, какие значения они будут иметь, кроме того, что они будут целыми числами от 0 и выше.
+0

Thanx! Я только что закончил одну реализацию, которая работает на 80%. Но после прочтения этой ссылки я думаю, что я могу лучше использовать маски и идентификаторы. – Espen

2

Вы можете решить эту проблему с простой математикой, хотя может быть лучше уже встроен.

Просто создать объект, который удерживает позицию каждого пальца, когда срабатывает событие .ACTION_POINTER_X_UP и логический объект, который содержит какой тип touchmode вы использовали в последний раз.

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 (в случае = 1) заявление будет срабатывать, когда пользователь перемещает палец, как они пошли от нескольких до одного прикосновения.

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

или

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