I den siste Android tutorial, vi dekket ved hjelp av en tråd for å trekke til et lerret i Android. I denne opplæringen, vil vi bygge videre på denne koden for å håndtere berøringsskjerm hendelser, og spesielt for å flytte den drivende boble rundt på skjermen som svar til brukeren berøre skjermen.
Når du gjør noe samordne-basert på Android er det lurt å sjekke opprinnelsen og retning av koordinatsystemet før du begynner. Ikke alle av dem bruker samme oppsett! Men i dette tilfellet, touchscreen koordinatene er de samme som standard 2D Opplysninger: Opprinnelsen er i øvre venstre hjørne, med x-aksen kjører mot høyre, og y-aksen kjører nedover. Dette betyr at vi kan bruke berørings koordinerer direkte som skjermkoordinater, uten noen transformasjon. (Dette er ikke tilfelle hvis du bruker OpenGL.)
Legge TouchEvent Håndtering til Vis
Vi vil bruke samme visning som forrige gang, BubbleSurfaceView. Alt vi trenger å gjøre er å legge en onTouchEvent () metode:
public class BubbleSurfaceView strekker SurfaceView implementerer SurfaceHolder.Callback {public boolean onTouchEvent (MotionEvent e) {float touchX = e.getX (); flyte nærtagende = e.getY (); bryteren (e.getAction ()) {case MotionEvent.ACTION_DOWN: thread.setBubble (touchX, nærtagende); gå i stykker; } Return true; }onTouchEvent () er en del av SurfaceView spec, så MotionEvent informasjonen vil automatisk bli sendt til din SurfaceView. Alt du trenger å gjøre er å skrive en metode for å håndtere det. Med et enkelt tilfelle, som her, er det ikke noe reelt behov for å skape touchX og nærtagende verdier (du kan bruke e.getX () og e.getY () direkte); men det er lurt å bruke disse verdiene for enkelt vedlikehold som koden blir mer komplisert
Denne koden reagerer på en ACTION_DOWN hendelse (og bare til den hendelsen.); det vil si når brukeren setter fingeren ned på skjermen. Siden (som per forrige tutorial) selve tegningen på vår lerret blir håndtert av en uavhengig tråd, må vi passere berørings informasjon i BubbleThread. BubbleThread.setBubble () er enkel:
klasse BubbleThread strekker Tråd {beskyttet void setBubble (float x, float y) {bubbleX = x; bubbley = y; }bubbleX og bubbley holde de sentrale koordinater for vår boble. Som run () metoden i denne diskusjonen er stadig redrawing skjermen, når boblen sin koordinater blir tilbakestilt, det vil bli tegnet på nytt på det nye stedet.
kompilere koden og kjøre den på telefonen din for å se boblen som blir tegnet på nytt uansett hvor du trykker på skjermen (og deretter drivende fra den posisjonen, som i koden fra forrige tutorial).
Håndtering Andre bevegelseshendelser
Vi kan enkelt endre dette til å håndtere ACTION_UP i stedet; bare erstatning ACTION_UP for ACTION_DOWN i koden ovenfor, kompilere og kjøre, og du vil se at nå boblen bare flytter posisjon når du løfter fingeren.
Hva om ACTION_MOVE? Kan vi endre denne metoden for å gjøre boble følge fingeren som du trekker den rundt på skjermen? API gjør dette også svært straighforward. EditonTouchEvent () for å se slik ut:
public boolean onTouchEvent (MotionEvent e) {float touchX = e.getX (); flyte nærtagende = e.getY (); bryteren (e.getAction ()) {case MotionEvent.ACTION_DOWN: thread.setBubble (touchX, nærtagende); gå i stykker; case MotionEvent.ACTION_MOVE: thread.setBubble (touchX, nærtagende); gå i stykker; case MotionEvent.ACTION_UP: thread.setBubble (touchX, nærtagende); gå i stykker; } Return true;}ACTION_MOVE er en konstant returnert hver gang det er en endring i løpet av en gest; dvs. mellom en ACTION_DOWN og ACTION_UP hendelsen. Så hver gang du beveger fingeren litt på skjermen, er en MotionEvent tilbake, og vi kan få koordinatene til fingeren nye posisjon og endre boblen plassering på tegningen tråden. Når arrangementet er over (anACTION_UP hendelse skjer), vi slutte å sende nye boble steder, og boblen går tilbake til drifting.
Det finnes et stort antall andre MotionEvents, også, som alle er beskrevet i MotionEvent API. Som du ser er det, kan du også få annen informasjon om berørings hendelser. Her er en rask eksempel på hvordan man kan få lang tid at en rekke touch-hendelser har tatt, igjen ved å redigere onTouchEvent ():
public boolean onTouchEvent (MotionEvent e) {//få touchX og nærtagende bryteren ( e.getAction ()) {//.... andre tilfeller ... saken MotionEvent.ACTION_UP: thread.setBubble (touchX, nærtagende); flyte totalTime = e.getEventTime () - e.getDownTime (); Toast.makeText (CTX, "Touch tid i ms var" + totalTime, Toast.LENGTH_SHORT) .vis (); gå i stykker; } Return true;}getDownTime () returnerer den tiden (i millisekunder) av forskudds touch som startet den nåværende kjede av bevegelseshendelser. getEventTime () returnerer den tiden (i millisekunder) av dagens bevegelse hendelse. Her, så kan vi få den varigheten som brukerens finger var å dra boblen rundt på skjermen (tiden mellom den første ned hendelsen, og den nåværende opp hendelse), og dukker opp en Toast melding for å fortelle dem. Anmeldelser
Til slutt, en rask praktisk notat om threading. Det er mulig, hvis tegning til lerretet tar noen betydelig tid, for å starte kjøringen () -metoden, mens tråden fremdeles er i gang, og prøver å trekke duken etter at den har blitt stoppet, noe som kaster en feil. Jo mer komplisert koden din blir, jo mer sannsynlig er det at dette vil skje. For å unngå dette, legg til en sjekk todoDraw ():
private void doDraw (lerret lerret) {if (run) {canvas.restore (); canvas.drawColor (Color.BLACK); canvas.drawCircle (bubbleX, bubbley, 50, maling); }}Å kunne reagere på bevegelse og berøring hendelser er en viktig del av å gjøre mest mulig ut av Android API, og det er et utvalg av kompleks informasjon tilgjengelig om berørings hendelser for å tillate deg å få mest mulig ut av dem. Lek litt med den informasjon som er tilgjengelig fra API for å se hva annet du kan gjøre boblen gjøre, eller hva annet du kan gjøre med det. I neste opplæringen, vil vi ta en titt på multi-touch-hendelser. Å ha mer enn én finger på skjermen