2010-11-19 5 views
8

Also entwickle ich eine Anwendung, die Multitouch verarbeiten muss. Grundsätzlich möchte ich Single Touch zum Drehen (das ist kein Problem). Und Multitouch zum Scrollen.Wie für Multitouch zu codieren

Ich habe den grundlegenden Code in, aber ich habe Probleme, wenn der Wechsel von Single zu Multitouch und umgekehrt vera, auftreten. Grundsätzlich ruckt die Bewegung, weil die mittlere Position des Multitouchs (zwei Finger) und die absolute Position des einzelnen Fingers entfernt sind. Wenn ich also zwei Finger auf dem Bildschirm habe, bilden sie eine mittlere Position und heben dann einen Finger, es wäre wie eine schnelle Bewegung von dieser mittleren Position zur absoluten Einzelfingerposition. Das wird die Bewegung sein, die ich nicht will.

Dies ist mein Code:

@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; 
    } 
} 

Die OnTouchDown Funktion der Kamera stellt nur den ersten Wert des Touch bewegen. Deshalb benutze ich es auch in der Aufwärtsbewegung, um einen neuen Anfangswert für die Single-Touch-Bewegung zu setzen, wenn ich von einem Multitouch komme.

Ich hoffe jemand weiß, was mein Problem ist und kann mir weiter helfen.

Antwort

10

starten hier, wenn Sie es nicht bereits gelesen haben, geht es über eine Reihe von Dingen mit Multi-Touch in Android zu tun: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

ein paar Dinge über Ihre gepostet Code:

  1. Sie über nie ACTION_DOWN mit einer Zeigeranzahl von 2 sehen. ACTION_DOWN wird nur für den ersten Zeiger gesendet, der untergeht. Alle Finger, die den Bildschirm nach dem ersten berühren, senden ACTION_POINTER_DOWN.
  2. Nehmen Sie nicht nur bis zu 2 Finger Touch, es kann leicht mehr sein.
  3. Es ist viel einfacher, mit der maskierten Aktion zu arbeiten (verwenden Sie MotionEvent#getActionMasked()) als für jeden Zeigerindex einzeln zu codieren.
  4. Am Ende spielen Indizes nur eine Rolle für das Ziehen von Daten aus einem MotionEvent. Wenn Sie die Zeigerbewegung im Zeitverlauf verfolgen, verwenden Sie die Zeiger-ID.
  5. Zeiger-IDs sind nur Zahlen. Machen Sie keine Annahmen darüber, welche Werte sie haben werden, außer dass sie ganze Zahlen von 0 und höher sind.
+0

Danke! Ich habe gerade eine Implementierung abgeschlossen, die zu 80% funktioniert. Aber nachdem ich diesen Link gelesen habe, denke ich, dass ich besser mit Masken und IDs umgehen kann. – Espen

2

Sie können dies mit einfacher Mathematik lösen, obwohl es bereits eine bessere Art und Weise eingebaut sein kann.

einfach ein Objekt erstellen, das die Position der einzelnen Finger hält, wenn das .ACTION_POINTER_X_UP Ereignis ausgelöst wird, und ein logisches Objekt, das hält welche Art von Touchmode du zuletzt benutzt hast.

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; 

Weiter Ihre ACTION_MOVE (innerhalb der Fall = 1) Anweisung wird ausgelöst, wenn der Benutzer seinen Finger bewegt, wie sie von Multi einzigen Berührung ging.

Nun wird, je nachdem, was Sie tun möchten, können Sie entweder die einzelne Bewegung ignorieren (die boolean ist Ihr Scheck), bis die .ACTION_UP Ereignis ausgelöst wird und Sie den boolean zurück auf false

oder

Sie rufen eine Methode auf, die basierend auf den gespeicherten Standortwerten und dem Finger, der sich noch auf dem Bildschirm befindet, einige Berechnungen durchführt. Die Mathematik sollte ziemlich einfach sein, aber ich weiß nicht, was du eigentlich machen willst.