Hvordan lage Android Multi-Touch Coding Enklere med GestureDetector

Multi-touch-skjermer er en morder funksjon i Android, så du kan godt ønske å aktivere multi-touch på programmet ditt. Som omtalt i forrige tutorial, "Hvordan håndtere Multi-Touch", kan du skrive din egen kode for å analysere flere peker hendelser manuelt. Men i tilfellet med vanlige multi-touch-bevegelser, som dobbelttrykk, bla, og flørt, du kan også forenkle saker ved å utnytte den innebygde GestureDetector. Les videre for mer om påvise bevegelser med GestureDetector

Implementing GestureDetector

Her er et helt grunnleggende første implementeringen av GestureDetector, som bare sender gest informasjon til loggen.

 public class GestureExample strekker aktivitet implementerer GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {private GestureDetector detektor; private String TAG = "GestureExample"; beskyttet void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_gesture_example); Detektoren = new GestureDetector (denne, dette); detector.setOnDoubleTapListener (denne); } Public boolean onTouchEvent (MotionEvent e) {this.detector.onTouchEvent (e); returnere super.onTouchEvent (e); } Public boolean onDown (MotionEvent e) {Log.d (TAG, "onDown:" + e.toString ()); return true; } Public boolean onFling (MotionEvent e1, MotionEvent e2, flyte velocityX, flyte velocityY) {Log.d (TAG, "onFling:" + e1.toString () + e2.toString ()); return true; } Public void onLongPress (MotionEvent e) {Log.d (TAG, "onLongPress:" + e.toString ()); } Public boolean onScroll (MotionEvent e1, MotionEvent e2, flyte distanceX, flyte distanceY) {Log.d (TAG, "onScroll:" + e1.toString () + e2.toString ()); return true; } Public void onShowPress (MotionEvent e) {Log.d (TAG, "onShowPress:" + e.toString ()); } Public boolean onSingleTapUp (MotionEvent e) {Log.d (TAG, "onSingleTapUp:" + e.toString ()); return true; } Public boolean onDoubleTap (MotionEvent e) {Log.d (TAG, "onDoubleTap:" + e.toString ()); return true; } Public boolean onDoubleTapEvent (MotionEvent e) {Log.d (TAG, "onDoubleTapEvent:" + e.toString ()); return true; } Public boolean onSingleTapConfirmed (MotionEvent e) {Log.d (TAG, "onSingleTapConfirmed:" + e.toString ()); return true; }} 

Det er ganske mye kode her; men det meste av det er å håndtere de mange gest hendelser. I onCreate (), må du opprette en ny GestureDetector, og satt det som en OnDoubleTapListener (det er automatisk satt som et OnGestureListener). Deretter, i onTouchEvent (), er this.detector.onTouchEvent (e) linje avgjørende. Uten det, vil ingen av hendelsene skal sendes til detektoren, og ingen av dine nøye utformede gest metoder vil kjøre. Det er også viktig å kalle super gjennomføring etter det.

De ulike bevegelses metodene er delt mellom OnGestureListener (onDown (), onFling (), onLongPress (), onScroll (), onShowPress (), og onSingleTapUp () ) og OnDoubleTapListener (onDoubleTap (), onDoubleTapEvent (), og onSingleTapConfirmed). De doble tappe hendelser blir brukt til å skille mellom en dobbel trykk og en klar enkelt trykk (dvs. et enkelt trykk som ikke er i ferd med å bli etterfulgt av en andre trykk). Du kan også handle på de ulike delene av en dobbel trykk hendelse: den onDoubleTapEvent () -metoden branner på ethvert forhold som utgjør en del av et dobbelttrykk (inkludert ned, opp, og flytte hendelser), mens onDoubleTap () refererer til hele sett av hendelser som skaper bevegelsen, selv om MotionEvent parameter er den første ned-tap bare. Eksperimentere med disse kan hjelpe deg å passe din app nøyaktig til brukerens forventninger.

SimpleOnGestureListener

For å bruke OnGestureListener og OnDoubleTapListener, må du opprette alt
disse metodene, selv om du ikke bruker dem. Hvis du bare faktisk ønsker noen av dem, kan du extendSimpleOnGestureListener stedet. Alt dette gjør er å implementere metoder i både Lytter klasser og return false for dem alle. Du bare skrive din egen metode bare for de bevegelser som du bryr deg om. Merk at du
implementere onDown () for å gå tilbake sant, ellers andre gester kan bli ignorert, som onDown () skjer i starten av alle bevegelser. Hvis den returnerer false, blir hendelsen 'forbrukes' (ikke videre til andre bevegelses metoder)

Her er et eksempel på bruk av SimpleOnGestureListener:

 public class GestureExample strekker Aktivitet {private GestureDetector detektor;. private String TAG = "GestureExample"; beskyttet void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_gesture_example); detektor = new GestureDetector (dette, ny MyExampleGestureListener ()); } Public boolean onTouchEvent (MotionEvent e) {this.detector.onTouchEvent (e); returnere super.onTouchEvent (e); } Class MyExampleGestureListener strekker GestureDetector.SimpleOnGestureListener {private static endelige String TAG = "MEGL"; public boolean onDown (MotionEvent e) {Log.d (TAG, "onDown:" + e.toString ()); return true; } Public boolean onScroll (MotionEvent e1, MotionEvent e2, flyte distanceX, flyte distanceY) {Log.d (TAG, "onScroll:" + e1.toString () + e2.toString ()); return true; }}} 

For resten av denne opplæringen, kan du bruke en av settene med kode ovenfor for å implementere metoder.

Bruke hendelser

Vi er nå kommer til å bruke noen av koden fra BubbleMove program i tidligere tutorials, for å trekke en boble, og deretter gjøre det svare på en bokrull gest. Vi vil gjøre dette med SimpleOnGestureListener, for å unngå å måtte gjennomføre alle de andre metodene, men du kan bruke OnGestureListener som omtalt ovenfor. Vi kommer til å flytte gest detektere kode ut av hovedaktiviteten og inn i View. Så GestureExample ser nå slik ut:

 public class GestureExample strekker Aktivitet {beskyttet void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (ny GestureExampleView (denne)); }} 

og alt arbeidet er gjort i GestureExampleView:

 public class GestureExampleView strekker SurfaceView implementerer SurfaceHolder.Callback {private SurfaceHolder sh; privat endelige Paint maling = new Maling (Paint.ANTI_ALIAS_FLAG); private GestureDetector detektor; private int bubbleX = 100; private int bubbley = 200; private int bubbleDiam = 50; offentlig GestureExampleView (Context kontekst) {super (sammenheng); sh = getHolder (); sh.addCallback (denne); setLongClickable (true); paint.setColor (Color.BLUE); paint.setStyle (Style.FILL); detektor = new GestureDetector (kontekst, ny MyExampleGestureListener ()); } Public void surfaceCreated (SurfaceHolder holder) {drawBubble (); } //Også implementere surfaceChanged () og surfaceDestroyed () (kan være tom) private void drawBubble () {lerret lerret = sh.lockCanvas (); canvas.drawColor (Color.BLACK); canvas.drawCircle (bubbleX, bubbley, bubbleDiam, maling); sh.unlockCanvasAndPost (lerret); } Public boolean onTouchEvent (MotionEvent e) {this.detector.onTouchEvent (e); returnere super.onTouchEvent (e); } Class MyExampleGestureListener strekker GestureDetector.SimpleOnGestureListener {public boolean onDown (MotionEvent e) {return true; } Public boolean onScroll (MotionEvent e1, MotionEvent e2, flyte distanceX, flyte distanceY) {bubbley = bubbley - (int) distanceY; drawBubble (); return true; }}} 

Det er en spesielt viktig linje i GestureExampleView konstruktør:

 setLongClickable (true); 

Uten dette, vil den eneste bevegelse hendelse du vil se bli onDown (); alt annet vil bli ignorert. (Denne linjen er bare nødvendig for en tilpasset View, ikke for en vanlig hoved aktivitet.)

Annet enn dette, bør alt være kjent fra enten denne opplæringen eller forrige; skaper vi en overflate, tegne en boble, og deretter sette opp GestureListener. Igjen, husk at det er viktig å gjennomføre onDown () for å gå tilbake sant. Deretter bruker vi Y avstand til å flytte boble Y, og tegne det, noe som gir en illusjon av rulling. Merk at distanceY er avstanden rullet langs Y-aksen siden siste oppfordring til onScroll (), mens e1 er den aller første ned bevegelse hendelse som startet rulling, og e2 er den nåværende bevegelse hendelsen som utløste den nåværende onScroll () kall. Siden en bokrull består av en serie av onScroll () kaller, er ikke distanceY den samme som Y avstand mellom e1 og e2.

Hvis du vil flytte boblen sidelengs samt opp og ned, kan du selvfølgelig legge bare en enkelt linje:

 bubbleX = bubbleX - (int) distanceX; 

Du kan leke seg mer med de andre øvelsene for å se hvordan de fungerer - kan det være lurt å flytte boble for en dobbelt pek, men ikke en eneste-tap, for eksempel.

GestureDetectorCompat

Faktisk, selv om koden ovenfor fungerer fint for de siste Android-versjoner, er det nå anbefalt at der det er mulig, bruker du GestureDetectorCompat fra Support Library, for å øke kompatibilitet med eldre versjoner av Android. Sjekk tilbake hit for neste tutorial i denne serien for å lære mer om Support Library og hvordan å pakke den med din app. Anmeldelser