"Turn" Android Gesture handling secrets

Source: Internet
Author: User

Why let the user use scroll when sliding (fling) is more efficient than moving (scroll)? On mobile devices with a small footprint and a lot of data, it is difficult to display the content scroll far behind, in which case fling is more appropriate.

Note: Scroll indicates how much distance the finger slips, and how much distance the interface follows, while the fling is based on your sliding direction and weight, and automatically slides a distance.

Filing gestures are widely used in Android interactive design: The sliding page of the ebook, the ListView swipe to delete item, the swipe to unlock, and so on. So how to detect the user's fling gesture is very important. But how do we get fling news? How to know the direction of fling, where to start from where to end? And how do you determine if the current gesture is fling rather than scroll?

In my recent project ROOM5, I was faced with the problem of an already-existing iOS project that is now going to be an Android version.

Before we deal with sliding animations, we need to detect the fling event, which is more complicated for beginners than it looks. This is because there is no obvious boundary between the three events of touch, scroll, fling. Scroll always happens before fling, and touch always takes place before scroll, the swipe screen (fling) always needs to touch the screen first (touch) and move on the screen (scroll). How do we know that sliding (fling) is not intercepted by touch events? The answer is to use several classes about gesture (gesture) processing.

I have written a demonstration of how these several classes are used in conjunction with the example program, where you can get the full source:Https://github.com/ericacooksey/FlingDemo This demo describes the entire process of capturing fling events. Here is the initial interface after running the APK:

When a touch,scroll or fling event is received, the name of the event is displayed on the interface and the most recent occurrence appears at the top. Here is the text that is output on the interface when you swipe from the top down (fling):

This picture gives you a general idea of the flow of events: View receives several scroll events, each with a touch event before each scroll event. The speed of the y-axis is rapidly increasing during the scroll event, until the final fling event is triggered. Let's take a look at the key code here .

First, we implemented the View.ontouchlistener to intercept the touch event of the view. I have temporarily omitted the code for sliding speed tracking (ellipsis), which we will discuss later. Here is the main implementation of the touch event trigger will be called back to the method, the method is registered to the corresponding view (here is TextView), the following is the code fragment.

1Mtouchlistener =NewVelocitytrackingtouchlistener ();2 //Initialize the TextView which 'll be a used to display the logged events3Mtextview =(TextView) Findviewbyid (R.id.mytextview);4 Mtextview.setontouchlistener (mtouchlistener);5 Private classVelocitytrackingtouchlistenerImplementsView.ontouchlistener { 6 @Override7      Public BooleanOnTouch (view view, Motionevent motionevent) {8         ......9 mgesturedetector.ontouchevent (motionevent);Ten         return true; One     } A}

Mgesturedetector is an example of gesturedetector. The Ontouch callback method receives the touch event before sending the event to view. Any event that might be related to a touch event (such as Click) is intercepted by this callback method. We give the touch event to Gesturedetector, so the role here is to pass motionevent to Gesturedetector's Ontouchevent method before passing the touch event. Start by judging what the current gesture is. Here is the code snippet that declares the Gesturedetector variable:

1 // instantiate a gesture listener to consume scroll and fling events 2 New flingdetector (); 3 // Pass the Flingdetector to Mgesturedetector to receive the appropriate callbacks 4 New Gesturedetector (this, flingdetector);

Where Flingdetector is a class that we inherit from Simpleongesturelistener. The advantage of using Simpleongesturelistener is that it completes all the empty implementations of all the Gesturedetector.ongesturelistener interfaces, so we just need to rewrite the callback method that is needed.

1 Private classFlingdetectorextendsGesturedetector.simpleongesturelistener {2      PublicFlingdetector () {3         Super();4     }5 @Override6      Public BooleanOnfling (motionevent E1, motionevent E2,floatVelocityx,7     floatvelocityy) {8UPDATETEXT ("in Onfling");9         return true;Ten     } One @Override A      Public BooleanOnscroll (motionevent E1, motionevent E2,floatDistancex,floatDistancey) { -UPDATETEXT (String.Format ("onscroll velocity = (%f,%f)", Mtouchlistener.xvelocity, mtouchlistener.yvelocity)); -         return false; the     } -}

As a summary, here is a review of the above series of processes:

(1) The Ontouchlistener registered by view intercepts the touch event.

(2) Ontouchlistener's callback method Ontouch (view view, Motionevent motionevent) passes motionevent to Gesturedetector.

(3) Implement a ongesturelistener and register it with Gesturedetector so that the callback method that handles the specific gesture in the Ongesturelistener can be triggered.

Note that each method of Ongesturelistener returns a Boolean value that indicates whether the motionevent is "consumed" after the current method has ended, that is, if it continues to be passed, true means that it is consumed, and vice versa. can continue to pass. Recall that the filing we mentioned above occurred after scroll, scroll occurred after touch, and we wanted to receive the fling gesture, so we returned false in Onscroll and returned true in fling.

But now the question is, what if we want a view that can be scroll or fling? For example, a billing interface we want Sroll to view the bill and use the fling operation to represent Swipe-to-pay. If you refer to the above fling event, it will be found that onscroll occurred 5 times before the onfling triggered. So if we respond to the Onscroll event, then the user will feel unnatural when fling operation, because scroll's interference with our expected interaction.

We can simply ignore the scroll and leave the implementation in the onscroll empty, but in this case, if the user's finger is slowly sliding to see what's behind, it will not respond. It is best to judge whether the scroll will lead to fling in scroll. In this case, Android Velocitytracker comes in handy. First, take a peek at the scroll. Gesture Output log:

Let's make a comparison of the speed in the y direction of this graph (only the scroll event) and the speed in the y direction of the previous graph (which produces the fling event). The reason for the Y speed is that we are all sliding from top to bottom in two experiments.

Scroll y-velocity Fling y-velocity
65 30085
140 23359
424 13787
660 10414
847 7449

As you can see, the y-velocity of the Rolling (scroll) event that produced the fling event is much higher than the scroll (scroll) that did not produce fling. We track the speed in the implementation of Ontouchlistener and add it to mvelocitytracker each time a touch event is received

1 Switch(action) {2      CaseMotionevent.action_down:3         if(Mvelocitytracker = =NULL) {4             //Retrieve A new Velocitytracker object to watch the velocity of a motion.5Mvelocitytracker =Velocitytracker.obtain ();6}Else {7             //Reset The velocity tracker back to their initial state.8 mvelocitytracker.clear ();9         }Ten         //Add A user ' s movement to the tracker. One mvelocitytracker.addmovement (motionevent); A      Break; -      CaseMotionevent.action_move: - mvelocitytracker.addmovement (motionevent); the         //When you want-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 -Xvelocity =mvelocitytracker.getxvelocity (Pointerid); +Yvelocity =mvelocitytracker.getyvelocity (Pointerid); A      Break; at      CaseMotionevent.action_cancel: -         //Return a Velocitytracker object back to being re-used by others. - mvelocitytracker.recycle (); -      Break; -}

The touch event is then passed to Flingdetector for analysis, and the flingdetector prints the Mvelocitytracker speed and the corresponding state (scroll or fling). After many experiments, we can find a reasonable decision whether the scroll will lead to the critical value of fling. Be engaged in judging whether the corresponding onscroll.

"Turn" Android Gesture handling secrets

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.