2012-06-30 12 views
7

Desidero che GestureOverlayView rilevi gesti puramente orizzontali e verticali.Gesti verticali e orizzontali in Android

Da http://android-developers.blogspot.com/2009/10/gestures-on-android-16.html

"orientamento: indica l'orientamento di scorrimento delle viste sotto In questo caso l'elenco scorre verticalmente, il che significa che qualsiasi gesti orizzontali (come ACTION_DELETE) possono immediatamente essere riconosciuti come gesto.. I gesti che iniziano con un tratto verticale devono contenere almeno un componente orizzontale da riconoscere: in altre parole, una semplice linea verticale non può essere riconosciuta come un gesto poiché sarebbe in conflitto con lo scorrimento della lista. "

Sembra come un fermo-22, se l'androide: orientamento è impostato verticale, posso avere solo colpi orizzontali, e se l'androide: orientamento sia impostato su orizzontale, posso avere solo colpi verticali. Come posso aggirare questo requisito?

+2

Hai mai trovato una soluzione a questo? – capcom

+0

No, non c'è ancora nessuna soluzione per Android ... – Bashevis

+0

Accidenti, quindi come faccio a fare ciò che mi serve? Ho davvero bisogno di farlo. Questo tutorial mostra su e giù in Gestures Builder http://www.vogella.com/articles/AndroidGestures/article.html, sebbene non utilizzato. Ecco la mia domanda, se vuoi dare un'occhiata, http://stackoverflow.com/questions/14246998/detecting-vertical-gestures. Non ha senso che non ci sia modo di farlo, altre app usano questo tipo di funzionalità tutto il tempo. – capcom

risposta

5

Mi sono imbattuto in questo problema in un hackathon. Non è possibile risolverlo con GestureOverlayView, quindi è necessario utilizzare gli eventi di movimento. GestureOverlayView tuttavia funziona con gesti leggermente più "dettagliati", come un cerchio. Quello che ho notato è che GestureOverlayView funziona al meglio per le figure chiuse. Quindi, sensore motionEvent è. Ho trovato il codice here. Ho modificato anche la risposta di Gav per gli swip verticali. Non l'ho provato, ma è positivo che dovrebbe funzionare.

Ecco un esempio:

public class SelectFilterActivity extends Activity implements OnClickListener 
{ 

private static final int SWIPE_MIN_DISTANCE = 120; 
private static final int SWIPE_MAX_OFF_PATH = 250; 
private static final int SWIPE_THRESHOLD_VELOCITY = 200; 
private GestureDetector gestureDetector; 
View.OnTouchListener gestureListener; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    /* ... */ 

    // Gesture detection 
    gestureDetector = new GestureDetector(new MyGestureDetector()); 
    gestureListener = new View.OnTouchListener() { 
     public boolean onTouch(View v, MotionEvent event) { 
      return gestureDetector.onTouchEvent(event); 
     } 
    }; 

} 

class MyGestureDetector extends SimpleOnGestureListener { 
    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     try { 
      // downward swipe 
      if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) 
       Toast.makeText(SelectFilterActivity.this, "Downward Swipe", Toast.LENGTH_SHORT).show(); 
else if (Math.abs(e2.getY() - e1.getY()) > SWIPE_MAX_OFF_PATH && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) 
       Toast.makeText(SelectFilterActivity.this, "Upward Swipe", Toast.LENGTH_SHORT).show(); 
      // right to left swipe 
      else if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show(); 
      } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show(); 
      } 
     } catch (Exception e) { 
      // nothing 
     } 
     return false; 
    } 

} 

aggiungervi il punto di vista in cui desideri rilevamento gesto,

// Do this for each view added to the grid 
    imageView.setOnClickListener(SelectFilterActivity.this); 
    imageView.setOnTouchListener(gestureListener); 

Saluti a Gav per il codice!

+0

L'ho già fatto nel mio codice, ma grazie per la risposta. Il fatto è che voglio tutti i gesti puramente verticali e orizzontali, insieme a tutto ciò che disegno da gestureoverlayview. Certo, puoi incappare in giro con motioneventi per rilevare un cerchio e così via, ma è un vero dolore. Non vedo perché questo è così difficile da fare in Android. Comunque, +1 per una buona risposta. Penso che per ora finirò con GestureDetector e implementerò alcuni dei miei gesti multifinger per aggiungere funzionalità extra in termini di gesti. – capcom

+0

Si noti inoltre che quando ho offerto il premio, ho specificamente menzionato che la risposta non deve includere GestureDetector. Ma molte grazie comunque. – capcom

+0

@capcom In qualsiasi momento, ma fammi sapere se puoi far funzionare gestureOverlayView. Ho provato molto, ho dovuto fare gesti più complessi, i semplici passaggi non sembrano funzionare. –

0
non

Forse il modo migliore per andare su di esso, ma si poteva ignorare il comportamento predefinito estendendo GestureOverlayView

Avresti bisogno di override del metodo private Rect touchMove(MotionEvent event) e sbarazzarsi del controllo dell'orientamento:

if (box.squareness > mGestureStrokeSquarenessTreshold || 
    (mOrientation == ORIENTATION_VERTICAL ? 
     angle < mGestureStrokeAngleThreshold : 
     angle > mGestureStrokeAngleThreshold)) { 

    mIsGesturing = true; 
    ... 
    ... 
} 

È l'unico posto in cui viene utilizzato l'orientamento, quindi non è necessario apportare modifiche estese. Solo una semplice estensione/override.

Naturalmente, per farlo destra, devi aggiungere un ORIENTATION_NONE e verificare contro che, come hanno fatto per il Replicant Project, ma immagino che dipende da se avrete mai bisogno di nuovo la funzionalità.

+0

Sembra interessante, proverò sicuramente a farti sapere. – capcom

0

Hai visto http://developer.android.com/training/gestures/index.html? Ho bisogno di un po 'più di informazioni su cosa stai cercando di fare con i gesti orizzontale e verticale per dare consigli più specifici. Ma avere un'area tattile che fa una cosa con i salti orizzontali e un'altra cosa con i salti verticali è sicuramente possibile. È anche importante non cercare linee perfettamente dritte, poiché i tuoi utenti non saranno in grado di realizzarle.

Modifica (1): Hai visto http://www.vogella.com/articles/AndroidGestures/article.html? Vogella sembra implicare nel suo esempio che puoi avere un gesto in su e gesti laterali nello GestureOverlayView. È questo che stai cercando di fare?

+0

Ho già visto quel link. Quello che sto cercando di fare è abbastanza semplice: voglio usare gesti personalizzati dalla classe GestureOverlayView, insieme a gesti verticali e orizzontali. Quella classe, tuttavia, non consente gesti "puramente" orizzontali/verticali perché interpreta quelle azioni come a scorrimento (afaik). Non ho contenitori scorrevoli a mio avviso. Per puro verticale/orizzontale, in realtà non intendo dire che le linee devono essere perfettamente dritte. Solo all'incirca. Non sto chiedendo all'utente di fare qualcosa di innaturale. Grazie. – capcom

+0

La mia domanda è l'uso dei 2 gesti. C'è un "GestureDetector' in grado di riconoscere i gesti di scorrimento, quali sono i salti orizzontali e verticali (anche quando non si scorre il contenuto di un contenitore). C'è un'intercettazione al tocco che significa che una vista contenente può mantenere gli eventi di movimento per se stessa in alcune situazioni e trasferirli a una vista figlio in altre situazioni. –

+0

La complessità di ciò che si vuole fare è legata al fatto che non ci si può aspettare linee rette dall'utente. Non ti stavo accusando di volerlo. Ciononostante, significa che i gesti di "rilevamento" devono essere restrittivi in ​​modo che possa essere certo di un gesto mentre consente a un utente di eseguire tratti approssimativi. –

5

Tutto quello che dovete fare, è impostato il GestureStrokeAngleThreshold ad un valore più vicino a 90 (io ho usato 90f)

Il valore di default del threashold angolo è 40.0f a causa della quale i tuoi gesti verticali semplici sarebbero saltati

+0

ha funzionato per me. ") Grazie –

Problemi correlati