Applications can be implemented using Gesturedetector if complex gesture matching is required.
Implementation steps:
1, implement the Ongesturelistener class, can also inherit the Simpleongesturelistener class and then make the corresponding function of replication;
2, create a Gesturedetector class object, and then new a 1th step in the custom listener class object as a parameter to wear;
3. Call the Ongesturelistener.ontouchevent (ontouchevent) function when receiving the Motionevent event.
Some of the custom processing done for gesture matching is implemented in the gesture listener class.
Here are some simple analysis of the above three steps: First look at the Gesturedetector constructor
Public Gesturedetector (context context, Ongesturelistener Listener, Handler Handler) { if (Handler! = null) { mHa Ndler = new Gesturehandler (handler); } else { Mhandler = new Gesturehandler (); } Mlistener = listener; if (listener instanceof Ondoubletaplistener) { Setondoubletaplistener ((ondoubletaplistener) listener); } Init (context); }
From the constructor, it is seen that the new Gesturedetector object requires a Ongesturelistener object, which is stored in Mlistener if the gesture listener inherits the Simpleongesturelistener class. Then Setondoubletaplistener () is also called.The INIT function does some initialization functions without looking at it first.
Then look at the 3rd step ongesturelistener.ontouchevent (ontouchevent) function processing. This function is a little bit longer, read in segments
public boolean ontouchevent (motionevent ev) {if (minputeventconsistencyverifier! = null) {Minputev Entconsistencyverifier.ontouchevent (EV, 0); } final int action = Ev.getaction (); if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain (); } mvelocitytracker.addmovement (EV); Final Boolean Pointerup = (Action & motionevent.action_mask) = = motionevent.action_pointer_up; Final int skipindex = Pointerup? Ev.getactionindex ():-1; Determine focal point float SumX = 0, SumY = 0; Final int count = Ev.getpointercount (); for (int i = 0; i < count; i++) {if (Skipindex = = i) continue; SumX + = Ev.getx (i); SumY + = Ev.gety (i); } final int div = Pointerup? Count-1: Count; Final float focusx = sumx/div; Final float focusy = sumy/div; Boolean handled = FALSE;
Inputeventconsistencyverifier is used for debugging, Mvelocitytracker is a speed-tracking class object, followed by this code logic is to find a motionevent center point, This side of debugging found Getpointercount only a point, whether it is click or swipe. Then look down.
Switch (action & motionevent.action_mask) {case MotionEvent.ACTION_POINTER_DOWN:mDownFocus X = Mlastfocusx = Focusx; Mdownfocusy = Mlastfocusy = Focusy; Cancel Long Press and Taps canceltaps (); Break Case MotionEvent.ACTION_POINTER_UP:mDownFocusX = Mlastfocusx = Focusx; Mdownfocusy = Mlastfocusy = Focusy; Check the dot product of current velocities. If the pointer is opposing another velocity vector, clear. Mvelocitytracker.computecurrentvelocity (mmaximumflingvelocity); Final int upindex = Ev.getactionindex (); Final int id1 = Ev.getpointerid (Upindex); Final float x1 = mvelocitytracker.getxvelocity (ID1); Final float y1 = mvelocitytracker.getyvelocity (ID1); for (int i = 0; i < count; i++) {if (i = = Upindex) continue; Final int id2 = ev.geTpointerid (i); Final float x = x1 * mvelocitytracker.getxvelocity (ID2); Final float y = y1 * mvelocitytracker.getyvelocity (ID2); Final float dot = x + y; if (dot < 0) {mvelocitytracker.clear (); Break }} break; Case MotionEvent.ACTION_DOWN:if (Mdoubletaplistener! = null) {Boolean hadtapmessage = Mhandler . Hasmessages (TAP); if (hadtapmessage) mhandler.removemessages (TAP); if (mcurrentdownevent! = null) && (mpreviousupevent! = null) && hadtapmessage && Isconsidereddoubletap (mcurrentdownevent, mpreviousupevent, Ev)) {//This is a second tap Misdoubletapping = true; Give a callback with the first tap of the Double-tap handled |= Mdoubletaplistener.ondoubletap (mcurRentdownevent); Give a callback with down event of the Double-tap handled |= mdoubletaplistener.ondoubletapevent (EV) ; } else {//This is a first tap mhandler.sendemptymessagedelayed (tap, Double_tap_tim Eout); }} mdownfocusx = Mlastfocusx = Focusx; Mdownfocusy = Mlastfocusy = Focusy; if (mcurrentdownevent! = null) {mcurrentdownevent.recycle (); } mcurrentdownevent = Motionevent.obtain (EV); Malwaysintapregion = true; Malwaysinbiggertapregion = true; Mstilldown = true; Minlongpress = false; Mdeferconfirmsingletap = false; if (mislongpressenabled) {mhandler.removemessages (long_press); Mhandler.sendemptymessageattime (Long_press, Mcurrentdownevent.getdowntime () + tap_timeout + longpress_timeout); } mhandler.sendemptymessageattime (Show_press, Mcurrentdownevent.getdowntime () + tap_timeout); Handled |= mlistener.ondown (EV); Break
For the Action_down event, call Mlistener.ondown (EV), handle, Mlistener is the gesture listener class object defined in step 1th. For Motionevent.action_move events, call Mlistener.onscroll (mcurrentdownevent, Ev, SCROLLX, scrolly), function, Mcurrentdownevent is the point at which the current swipe gesture is pressed, the EV is the current touch point, and the SCROLLX, scrolly is the X/Y offset of the current touch point that follows the previous touch. For ACTION_UP events, call Mlistener.onsingletapup (EV) or mlistener.onfling (mcurrentdownevent, Ev, Velocityx, VelocityY); functions.
Not to be continued.