Brief Introduction to Android touch screen Gesture Recognition and android touch screen gesture
Most of the time, the use of touch screen Fling, Scroll and other Gesture (Gesture) operations will greatly improve the user experience of the application, such as rolling the screen in the browser using Scroll gestures, use Fling to flip pages in the reader. In Android, gesture recognition is implemented through GestureDetector. the OnGestureListener interface is implemented. However, William did not find an example after reading the official Android documentation. TouchPaint in API Demo only mentions onTouch event processing and does not involve gestures. Many people in the Android Developer discussion group have similar issues with me. In combination with the methods they mentioned and my experiments, I will give you a brief introduction to the implementation of Gesture Recognition in Android.
First, let's clarify some concepts. First, Android's event processing mechanism is implemented based on the Listener. Compared with the touch screen-related events we call today, we use onTouchListener. Secondly, all View subclasses can add listeners for a certain type of events by using methods such as setOnTouchListener () and setOnKeyListener. Third, Listener is generally provided in Interface (Interface) mode, which contains one or more abstract methods. We need to implement these methods to complete onTouch () and onKey. In this way, after an event Listener is set for a view and the abstract method is implemented, the program can dispatch a specific event to the view, the callbakc function is used to give an appropriate response.
Let's look at a simple example and use the simplest TextView to describe it (in fact, it is no different from the skeleton generated in the ADT ).
Java code
- Public class GestureTest extends Activity implements OnTouchListener {
- @ Override
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
- SetContentView (R. layout. main );
- // Init TextView
- TextView TV = (TextView) findViewById (R. id. page );
- // Set OnTouchListener on TextView
- TV. setOnTouchListener (this );
- // Show some text
- TV. setText (R. string. text );
- }
- @ Override
- Public boolean onTouch (View v, MotionEvent event ){
- Toast. makeText (this, "onTouch", Toast. LENGTH_SHORT). show ();
- Return false;
- }
We set an onTouchListener for the TextView instance TV, because the GestureTest class implements the OnTouchListener interface, so simply give this as a parameter. The onTouch method implements the abstract method in OnTouchListener. You only need to add the logic code here to make a response when you touch the screen, just like what we do here-to make a prompt.
Here, we can use the getAction () method of MotionEvent to obtain the Touch event type, including ACTION_DOWN, ACTION_MOVE, ACTION_UP, and ACTION_CANCEL. ACTION_DOWN refers to pressing the touch screen, ACTION_MOVE refers to moving the affected device after pressing the touch screen, ACTION_UP refers to loose touch screen, and ACTION_CANCEL is not directly triggered by the user (so it is not in the scope of discussion today, see ViewGroup. onInterceptTouchEvent (MotionEvent )). After obtaining coordinates using getRawX (), getRawY (), getX (), getX (), and getY () methods based on different user operations, we can implement operations such as dragging a button, drag a scroll bar. In standby mode, you can refer to the MotionEvent Class documentation, or the TouchPaint example.
Back to what we want to talk about today, how can we identify users' Gesture when we capture Touch operations? Here we need the help of the GestureDetector. OnGestureListener interface, so our GestureTest class becomes like this.
Java code
- Public class GestureTest extends Activity implements OnTouchListener,
- OnGestureListener {
- ....
- }
Then, in the onTouch () method, we call the onTouchEvent () method of GestureDetector and hand over the captured MotionEvent to GestureDetector to analyze whether there is a proper callback function to process user gestures.
Java code
- @ Override
- Public boolean onTouch (View v, MotionEvent event ){
- // OnGestureListener will analyzes the given motion event
- Return mGestureDetector. onTouchEvent (event );
- }
Next, we have implemented the following six Abstract METHODS: onFling (), onScroll (), and onLongPress. I have written the meaning of the gesture represented by each method in the comments. You can see it at a glance.
// Touch the touch screen, triggered by one MotionEvent ACTION_DOWN
Java code
- @ Override
- Public boolean onDown (MotionEvent e ){
- // TODO Auto-generated method stub
- Toast. makeText (this, "onDown", Toast. LENGTH_SHORT). show ();
- Return false;
- }
- // Touch the touch screen, which has not been released or dragged, triggered by one MotionEvent ACTION_DOWN
- // Note the difference between onDown () and onDown (), emphasizing that the status is not released or dragged.
- @ Override
- Public void onShowPress (MotionEvent e ){
- // TODO Auto-generated method stub
- }
// The user (after touching the touch screen) is released and triggered by one MotionEvent ACTION_UP
Java code
- @ Override
- Public boolean onSingleTapUp (MotionEvent e ){
- // TODO Auto-generated method stub
- Return false;
- }
// The user presses the touch screen and moves quickly before releasing it. It is triggered by one MotionEvent ACTION_DOWN, multiple ACTION_MOVE, and one ACTION_UP.
Java code
- @ Override
- Public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX,
- Float velocityY ){
- // TODO Auto-generated method stub
- Return false;
- }
- // The user presses the touch screen for a long time and is triggered by multiple MotionEvent ACTION_DOWN
- @ Override
- Public void onLongPress (MotionEvent e ){
- // TODO Auto-generated method stub
- }
- // Press the touch screen and drag it. It is triggered by one MotionEvent ACTION_DOWN and multiple ACTION_MOVE operations.
- @ Override
- Public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX,
- Float distanceY ){
- // TODO Auto-generated method stub
- Return false;
- }
Let's try to process an onFling () event. I wrote the meaning of each parameter in the onFling () method in the annotation. Note that the Fling event processing code is used, in addition to the coordinates contained in the First ACTION_DOWN triggering Fling and the last ACTION_MOVE, we can also use the moving speed on the X or Y axis as a condition. For example, in the following code, we can only process a user moving more than 100 pixels and moving more than 200 pixels per second on the X axis.
Java code
- @ Override
- Public boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX,
- Float velocityY ){
- // Parameter explanation:
- // E1: 1st ACTION_DOWN MotionEvent
- // E2: The last ACTION_MOVE MotionEvent
- // VelocityX: moving speed on the X axis, pixel/second
- // VelocityY: The moving speed on the Y axis, pixel/second
- // Trigger condition:
- // The coordinate displacement of the X axis is greater than FLING_MIN_DISTANCE, and the movement speed is greater than that of FLING_MIN_VELOCITY pixels/s.
- If (e1.getX ()-e2.getX ()> FLING_MIN_DISTANCE
- & Math. abs (velocityX)> FLING_MIN_VELOCITY ){
- // Fling left
- Toast. makeText (this, "Fling Left", Toast. LENGTH_SHORT). show ();
- } Else if (e2.getX ()-e1.getX ()> FLING_MIN_DISTANCE
- & Math. abs (velocityX)> FLING_MIN_VELOCITY ){
- // Fling right
- Toast. makeText (this, "Fling Right", Toast. LENGTH_SHORT). show ();
- }
- Return false;
- }
The problem is that if we try to run the program at this time, you will find that we don't get the desired results at all. If we trace the code execution, we will find that the onFling () event has never been captured. This is the problem that plagued me at the beginning. Why?
I found the answer in the discussion group's Gesture detection post, that is, we need to add the following code in onCreate TV. setOnTouchListener (this.
TV. setLongClickable (true); only in this way can the view process be different from the hold (I .e., ACTION_MOVE, or multiple ACTION_DOWN) of the Tap (touch). We can also use android in the layout definition: longClickable to do this.
The problem encountered this time is similar to the problem of setOnKeyListener in the previous MapView. In fact, it is not comprehensive enough to understand the SDK, and it is good to remember it once. However, Google does need to improve its documentation. At least it can be stated in OnGestureListener that the conditions must be met to ensure that the gesture is correctly recognized.
Android touch screen gesture recognition is a simple introduction here, hoping to be useful to everyone. For the running effect, you can download the sourcecode of the Demo to try it out.