Android Touch Gesture Basics Official Document Overview
Touch Gesture Detection Basics
Gesture detection typically consists of two stages:
1. Get Touch event data
2. Parse the data to see if they meet some of the gestures your app supports.
Related APIs:
MotionEvent
Compatible version of:
MotionEventCompat
(Note that Motioneventcompat are not a replacement for the Motionevent class.) Rather, it provides static utility methods to which you pass your motionevent object in order to receive the desired actio N associated with that event.)
Touch event handling in general activity or view
The callback function of the onTouchEvent()
activity or view class receives the touch event.
In order to intercept the touch event, you need to overwrite the activity or view's Ontouchevent method.
You can also use the Setontouchlistener () method to add a listener to a View.OnTouchListener
click event. This allows you to handle click events without inheriting the view.
But if you need to handle gestures like double-click, long-Press, fling (fast-sliding), you need to take advantage of GestureDetector
classes.
The return value of the Ontouchevent method
The return value of the Ontouchevent method, If true, means that you have handled the touch event, and if it returns false, the event will continue to pass through the view stack until the event is processed.
It is important to note The ACTION_DOWN
event, and if it returns false, the listener will not be notified of the subsequent series ACTION_MOVE
and ACTION_UP
events.
Detect gestures
Android provides GestureDetector
classes to detect general gestures.
Basic use:
1. generates GestureDetector
an object (or gesturedetectorcompat object), and constructs a parameter to pass in to the Listener object.
The Listener object implements GestureDetector.OnGestureListener
the interface.
If you just want to take advantage of some of these gestures instead of all, then you can choose to inherit the Gesturedetector.simpleongesturelistener class, which is an adapter pattern, that is, this class implements the GestureDetector.OnGestureListener
interface, which provides an empty implementation for all of the methods (the return value is false), and when inheriting the Gesturedetector.simpleongesturelistener class, the subclass only needs to overwrite the method of interest. The other method is an empty implementation.
2. in order for an GestureDetector
object to receive an event, it needs to overwrite the method in view or activity onTouchEvent()
and pass the event to the detector object.
An example:
Package Com.example.hellogesturedetector;import Android.os.bundle;import Android.app.activity;import Android.util.log;import Android.view.gesturedetector;import Android.view.GestureDetector.OnDoubleTapListener; Import Android.view.gesturedetector.ongesturelistener;import Android.view.menu;import android.view.MotionEvent; Import Android.view.viewgroup;import Android.widget.textview;public class Hellogesturedetectoractivity extends Activity {private static final String Log_tag = "Hellogesture"; Private Gesturedetector mgesturedetector = null; Private TextView Mgesturetextview = null; Private TextView Mdoubletaptextview = null; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_hello_gesture_detector); Mgesturetextview = (TextView) Findviewbyid (r.id.gesture); Mdoubletaptextview = (TextView) Findviewbyid (R.ID.DOUBLETAP); Constructing Gesturedetector objects, passing in listener objectsMgesturedetector = new Gesturedetector (this, mongesturelistener); Incoming double-click Listener Object Mgesturedetector.setondoubletaplistener (Mdoubletaplistener); } @Override public boolean ontouchevent (Motionevent event) {//passes the event to the gesture detection object in the Ontouchevent method, otherwise the callback function in the gesture listener object is not The Mgesturedetector.ontouchevent (event) that will be called; Return Super.ontouchevent (event); } private Ongesturelistener Mongesturelistener = new Ongesturelistener () {@Override public boolean Onsin Gletapup (motionevent e) {log.i (Log_tag, "onsingletapup:" + e.tostring ()); Mgesturetextview.settext ("Onsingletapup:"); return false; } @Override public void onshowpress (Motionevent e) {log.i (Log_tag, "onshowpress:" + e.tostring ( )); Mgesturetextview.settext ("onshowpress:"); } @Override public boolean onscroll (Motionevent E1, motionevent E2, float Distancex, float di Stancey) { LOG.I (Log_tag, "onscroll:" + e1.tostring () + "," + e2.tostring ()); Mgesturetextview.settext ("Onscroll"); return false; } @Override public void onlongpress (Motionevent e) {log.i (Log_tag, "onlongpress:" + e.tostring ( )); Mgesturetextview.settext ("onlongpress:"); } @Override public boolean onfling (Motionevent E1, motionevent E2, float Velocityx, float vel Ocityy) {log.i (Log_tag, "onfling:" + e1.tostring () + "," + e2.tostring ()); Mgesturetextview.settext ("onfling"); return false; } @Override public Boolean ondown (Motionevent e) {log.i (Log_tag, "Ondown:" + e.tostring ()); Mgesturetextview.settext ("Ondown:"); return false; } }; Private Ondoubletaplistener Mdoubletaplistener = new Ondoubletaplistener () {@Override public boolean onsing Letapconfirmed (Motionevent e) { LOG.I ("Log_tag", "onsingletapconfirmed:" + e.tostring ()); Mdoubletaptextview.settext ("onsingletapconfirmed:"); return false; } @Override public Boolean ondoubletapevent (Motionevent e) {log.i ("Log_tag", "Ondoubletapevent: "+ e.tostring ()); Mdoubletaptextview.settext ("ondoubletapevent:"); return false; } @Override public Boolean ondoubletap (Motionevent e) {log.i ("Log_tag", "Ondoubletap:" + e.tost Ring ()); Mdoubletaptextview.settext ("Ondoubletap:"); return false; } };}
According to the official network said:
For the return value of the Ondown () method, it is best to return true, since all gestures start with the Ondown () information.
If GestureDetector.SimpleOnGestureListener
you return false as the default implementation, the system will assume that you want to ignore the rest of the gesture, and then GestureDetector.OnGestureListener
The other methods will not be called.
But when the actual program is validated, it does not seem to have any effect on whether it returns true or false. (??)
Track motion Speed
There are many different ways to record movements in gestures, such as the starting and ending positions of pointer, the direction of pointer movement, the history of Gestures (through getHistorySize()
methods), and the speed of movement of pointer.
Android provides VelocityTracker
classes and Velocitytrackercompat classes to record the speed of touch events.
code example:
public class Mainactivity extends Activity {private static final String Debug_tag = "Velocity"; ... private velocitytracker mvelocitytracker = null; @Override public boolean ontouchevent (Motionevent event) {int index = Event.getactionindex (); int action = event.getactionmasked (); int pointerid = Event.getpointerid (index); Switch (action) {case MotionEvent.ACTION_DOWN:if (Mvelocitytracker = = null) { Retrieve a new Velocitytracker object to watch the velocity of a motion. Mvelocitytracker = Velocitytracker.obtain (); } else {//Reset the velocity tracker back to their initial state. Mvelocitytracker.clear (); }//Add a user ' s movement to the tracker. Mvelocitytracker.addmovement (event); Break Case Motionevent.action_move:mVelocitytracker.addmovement (event); When you want to determine the velocity, call//Computecurrentvelocity (). Then call getxvelocity ()//And Getyvelocity () to retrieve the velocity for each pointer ID. Mvelocitytracker.computecurrentvelocity (1000); Log velocity of pixels per second//best practice to use velocitytrackercompat where possible. LOG.D ("", "X Velocity:" + velocitytrackercompat.getxvelocity (Mvelocitytracker, Pointerid)); LOG.D ("", "Y Velocity:" + velocitytrackercompat.getyvelocity (Mvelocitytracker, Pointerid)); Break Case MotionEvent.ACTION_UP:case Motionevent.action_cancel://Return a Velocitytracker object b Ack to is re-used by others. Mvelocitytracker.recycle (); BReak; } return true; }}
Scrolling gestures
If a standard layout is likely to exceed its container boundaries, it can be nested in a ScrollView , so that a scrollable layout can be obtained and handled by Framewok.
Implementing a custom scroller should only be required in some special cases.
Scroller is used to create scrolling animations over time, using platform-standard scrolling physical parameters (friction, speed, etc.).
Scroller himself does not actually draw anything.
Scroller records the offset values for scrolling, but it does not apply these locations to your view and you need to do it yourself.
See: http://developer.android.com/training/gestures/scroll.html
Multi-Touch gestures
When multiple pointer touch the screen at the same time, the system generates the following events:
ACTION_DOWN
-for The first pointer that touches. This starts the gesture. The pointer data for this pointer are always on index 0 in the MotionEvent
.
ACTION_POINTER_DOWN
-for Extra pointers That's enter the screen beyond the first. The pointer data for this pointer are at the index returned by getActionIndex()
.
ACTION_MOVE
-A change has happened during A press gesture.
ACTION_POINTER_UP
-sent when a non-primary pointer goes up.
ACTION_UP
-sent when the last pointer leaves the screen.
You can rely on each pointer index and ID to track each pointer:
index:motionevent will put each pointer information in an array, and index is the array index. Most of the motionevent methods You use are using this index as the parameter.
ID: Each pointer also has an ID mapping that maintains a constant consistency (persistent) in the touch event, so that a single pointer can be traced throughout the gesture.
The order in which the pointer appears in a motion event is undefined, so the index of pointer is mutable in different events, but its ID remains the same as long as pointer remains active.
By getPointerId()
Obtaining the ID, you can track pointer in multiple motion event. Then for a continuous motion event, you can use the findpointerindex () method to get the index of the pointer of the specified ID in the current event.
Like what:
private int Mactivepointerid; public boolean ontouchevent (Motionevent event) { .... Get the pointer ID mactivepointerid = Event.getpointerid (0); // ... Many touch events later ... Use the pointer ID to find the index of the active pointer //and fetch its position int pointerindex = EVENT.F Indpointerindex (Mactivepointerid); Get the pointer ' s current position float x = event.getx (pointerindex); Float y = event.gety (pointerindex);}
The action to get motionevent should use the getactionmasked () method (or a compatible version of motioneventcompat.getactionmasked ()).
Unlike older versions of getaction () , getActionMasked()
methods are designed to work with multiple pointer.
It returns the action with the mask, without the bits pointer used for index.
You can use Getactionindex () to get index.
Drag and Zoom
Drag an object:
If Android 3.0 is above, you can use the new interface of view View.OnDragListener
see: Drag and Drop.
Other See also: http://developer.android.com/training/gestures/scale.html
Scaling can be used ScaleGestureDetector
.
ScaleGestureDetector
Can be GestureDetector
used together with the.
Touch Event Handling in ViewGroup
ViewGroup
The touch event handled is a bit cumbersome because it is possible that the target of the various touch events is not viewgroup but its child.
To ensure that each child receives the touch events correctly, it is necessary to overwrite the ViewGroup onintercepttouchevent () method.
If the onintercepttouchevent () method returns True, the motionevent is intercepted, it will not be passed to the child, but is passed to the onTouchEvent()
parent Method.
If you return truein the parent's onintercepttouchevent () method, the child view that was previously processing the touch event will receive one ACTION_CANCEL
, The subsequent events are all passed to the parent's ontouchevent.
If the onInterceptTouchEvent()
method returns false, the event continues to pass down the view structure, the parent does not intercept the event, and the parent's ontouchevent () method is not called.
Other:
viewconfiguration provides some constants.
The touchdelegate class can be used to set the touch area of a view.
Usage See: http://developer.android.com/training/gestures/viewgroup.html
Resources
Training:using Touch gestures
Http://developer.android.com/training/gestures/index.html
Android Touch Gesture Basics Official Document Overview 2