6 - 4 - Touch and Gestures - Part 1 (15-48)

7
[BLANK_AUDIO] Hi, I'm Adam Porter, and this is Programming Mobile Applications for Android Handheld Systems. If you use common applications that display maps or web pages, then you've probably used gestures like swiping to scroll a view, or inching and un-pinching your thumb and index finger to zoom in or zoom out. In this lesson, I'll start by discussing MotionEvents. Android uses this class to represent the movement in various input devices. Things like a mouse, a trackball, and most common of all, your finger. Next I'll discuss how Android takes these motion events and delivers them to views and other objects, so that your application can respond to them. And finally, I'll finish up with a discussion of how Android recognizes complex movement patterns or gestures, things like the pinch to zoom that I mentioned earlier. Android uses the MotionEvent class to represent movements in an input device. Such as a pen, a trackball, a mouse or your finger. An individual movement event contains several pieces of information. It has an action code, which indicates the kind of motion that has occurred. It also contains a variety of data associated with that motion. For instance, it has information about the time at which the event occurred, which device the event came from, the event's location. And if appropriate, how hard the device was pressed and more. And as I just said, this information will vary depending on the kind of input device involved. In the rest of this lesson, I'll focus particularly on finger touch events that are read by pressing a touch screen. Many touch screen devices today are multi touch devices. That means that they can register and track multiple touches all the same time In Android, multi touch devices emit one movement trace per touch source. And each of these touch sources is referred to as a pointer. When Android encounters a new pointer, it generates a unique

Transcript of 6 - 4 - Touch and Gestures - Part 1 (15-48)

[BLANK_AUDIO]Hi, I'm Adam Porter, and this isProgramming Mobile Applications forAndroid Handheld Systems.If you use common applications thatdisplay maps or web pages, thenyou've probably used gestures like swipingto scroll a view, orinching and un-pinching your thumb andindex finger to zoom in or zoom out.In this lesson, I'll start by discussingMotionEvents.Android uses this class to represent themovement in various input devices.Things like a mouse, a trackball, and mostcommon of all, your finger.Next I'll discuss how Android takes thesemotion events and deliversthem to views and other objects, so thatyour application canrespond to them.And finally, I'll finish up witha discussion of how Android recognizescomplexmovement patterns or gestures, things likethepinch to zoom that I mentioned earlier.Android uses the MotionEvent class torepresent movements in an input device.Such as a pen, a trackball, a mouse oryour finger.An individual movement event containsseveral pieces of information.It has an action code, which indicates thekind of motion that has occurred.It also contains a variety of dataassociated with that motion.For instance, it has information about thetime at which theevent occurred, which device the eventcame from, the event's location.And if appropriate, how hard the devicewas pressed and more.And as I just said, this information willvary depending on the kind of input deviceinvolved.In the rest of this lesson, I'll focusparticularly on finger touch eventsthat are read by pressing a touch screen.Many touch screen devices today are multitouch devices.That means that they can register andtrack multiple touches all the same timeIn Android, multi touch devices emit onemovement trace per touch source.And each of these touch sources isreferred toas a pointer.When Android encounters a new pointer, itgenerates a unique

ID that will remain constant for as longas that pointer is active.In some cases, Android will group multiplepointers within a single motion event.And in that case, each pointer within themotion event can be accessed by its index.But be aware, that that index is notthe same as the pointer's ID.The pointer ID is constant for as long asthe pointer is active.The index in which a pointer's data isstored however may not be.So let's talk about Motion Events in moredetail.Now as I said earlier Motion Events havean action code.When a gesture begins,motion events will be created, and theywill contain some of the following actioncodes.ACTION_DOWN, which indicates that a firstfingerhas been, has started touching the screen.ACTION_POINTER_DOWN, that means that we'vealready had an ACTION_DOWN,and now we have another finger that hasstarted touching the screen.ACTION_POINTER_UP.We've had an ACTION_POINTER and anACTION_POINTER_DOWN, and nowone of the fingers has stopped touchingthe screen.ACTION_MOVE.Some of the fingers that are touching thescreen have changed their position.ACTION_UP.The last of the fingers that was touchingthe screen has now stopped touching it.AndACTION_CANCEL.Something has prematurely canceled thecurrent gesture.While the gesture is playing out Androidwill tryto ensure that it's motion events obey thefollowing rules.Touches will go down one at a time.They will move as a group.So a single motion event can refer tomultiple pointers, andthey will come up one at a time or becancelled.When you need to process motion events,you canuse some of the following methods,getActionMasked which returns theaction code associated with the motionevent getActionIndex,which returns the index of the pointerassociated with this action code.

For example, if the action code is actionpointer down then you can usethis method to find the index of theparticular pointer that is justtouched down, getPointerId.Givenan index, this method returns the stableID of the pointerassociated with that index.GetPointerCount,which returns the number of pointersassociated with the motion event.GetX and getY, which return thex and y coordinates of the pointer storedat the current index.And findPointerIndex, which returns theindex associated with a given pointer ID.When a touch occurs on a view, Androidgenerates a motion event, and thenattempts to deliver that event to variousobjects, one of which is the view itself.Android delivers the motion event throughthe onTouchEvent method.This method can process the motion event,and should end,by returning true if the motion event hasbeen consumed,and false if it is not.Objects interested in receiving motionevents that occuron a given view, can register to receivethoseevents by implementing the views on touchlistener interface,and by registering the object with theview.setontouchlistener method.The listener's onTouch method will then becalled whenan event such as pressing, releasing, ordragging, occurs.And this method will be called before thetouchto view gets a chance to handle thattouch.And again, onTouch should return true ifit consumes the motion event.Or false if it doesn't.In the simplestcase, you can process each touch eventindependently.But applications often need or want toprocess multiple touches that are partof a more complex gesture.To do this, your code willneed to identify and process particularcombinationof touches for example, a double touchwill involve an ACTION_DOWN.And then and ACTION_UP and then anotherACTION_DOWN

and finally an ACTION_UP all in quicksuccession.To give some examples, suppose you start agesture by placing one finger down on thescreen.That will generate an ACTION_DOWN event.And might assign a pointer ID of zero forthat pointer.If you keep that finger down and move iton the screen, you might get severalaction move events associatedwith pointer ID zero.Suppose now thatyou put a second finger down.In that case you'll get an action pointerdown event, and this new pointer might getan ID, say of one.If you keep those fingers down and youmove them, you might get then severalaction move events associated with thepointer IDs zero and one.And if you now lift the first finger, thenyou'llget an action pointer up event, associatedwith pointer zero.And then, if you finally lift the lastfinger, you'll get an action up eventassociated with pointer ID 1.In the next example,we'll start as before, putting down thefirst finger.Moving it, putting down a second finger,and then moving those fingers again.But this time, however, we'll lift thesecond finger first.In this case, we get an action pointer upaction associated with pointer ID 1.And then finally, when we lift the lastfinger, we get the actionup Action associated with the pointer ID0.For a last example, we'll use threefingers.We'll put down the first finger, then thesecond, and then a third.And then we'll move the fingers, and thenwe'll lift them up.First lifting the second finger, then thefirstfinger, and then finally lifting the thirdfinger.Our first example application inthis lesson is calledtouchindicatetouchlocation.And this application draws a circlewherever the user touches the screen.The circle's color is randomly selected,and the application also then redrawsthe circle, following the user's finger,if it moves across the screen.

And finally, when the usertouches the screen in multiple locations.The size of the circles that are drawn,willchange to reflect the number of currentlyactive touches.Lets take a look at this application inaction.So here's my device.[BLANK_AUDIO]And now I'll start up the touch indicatetouch location application.When it starts, the screen is blankbecause I'm not touching the screen rightnow.Now I'll place one finger on the screenand that causes asingle circle to be drawn at the placewhere I've touched the screen.As I slide my finger along the screen, youcansee that the circle is redrawn, to trackmy finger movements.Now,I'll place a second finger on the screen.And that causes the second circle to bedrawn under that finger.And as you can see, the size of the twocircles, is nowabout half of what you saw when there wasonly a single circle.Now, here I'll take away the secondfinger, andthe first circle goes back to its originalsize.Now,I'll put the second finger back, and againthe two circles appear athalf size.And, I can drag these two fingers aroundthe screen, and the circles will follow mymovements, and finally here I'll put downmore fingers four, six, eight, ten.I'm out of fingers now.So now I'll move them around, andnow I'll start to take away some fingers.Eight, six, four, two, one.Now, let's take a look at the source codefor this application.Here's the application open in the IDE.Now I'll open the main activity.This coast, this code first creates a poolof custom views called marker views.Marker views will be used to mark thelocation of a single touch.Next, the code defines a set that holdsthe MarkerViews that are currently visibleon the display.And now down in onCreate, the code getsthe

FrameLayout that represents the main viewof this activity.And then it creates an OnTouchListener andsets this as the recipient ofthat listener's OnTouch callback.Let's look at that method.When the user touches the screen, thislistener's OnTouch method is called,and that method begins by checking theaction code for the new motion event.If the action code is ACTION_DOWN orACTION_POINTER_DOWN, then there's been anew touch.So the code creates and displays a newmarker view.The codedoes this by recording the pointer ID, andpointerindex for this event.It then takes a marker view from theinactive list.And it then adds that marker view tothe active set, using its pointer ID asthe key for this view.Next, it sets the location of this markerview, and thenit updates the total number of touches foreach currently visible marker view.And then it adds the marker view to theactivity's main view.Now if, instead, the action code wasACTION_UP, or ACTION_POINTER_UP.Then that means that a finger has beenlifted off the screen.So the code essentially undoeswhat we just finished talking about.Now, as before, the code begins byrecordingthe pointer ID and pointer index for thisevent.It then removes the marker view that wasassociated withthe finger that was just lifted from theactive set.It then adds that marker view back to theinactive list.And next, it updates the total numberof touches for each currently visiblemarker view.And then it removes the marker view fromthe activity's main view.And lastly, if theaction code is ACTION_MOVE.Then the code adjusts thelocation of the affected marker views, andinitiates their redrawing.The code does this by looping over thepointers in the motion event.For each one, it gets the marker view forthat

pointer then it checks whether thepointer's traveled some minimum distance.If so, it sets a new location for thatmarker view, and then calls invalidateon the MarkerView which indicates that theMarkerView wants to be redrawn.