History of the will "copy" of programmers! This Guards skills, good at the system source code for its own purposes!

Author: Chen Yang Che-hung edge &

It originated from a colleague asked me: "how elegant double-click the listener," this behavior?

In fact, many similar events related, we can refer to the system source code, because sometimes completely into the system the ability to have some trouble, we could easily achieve a wanted feature.

The above example colleague asked:

How elegant double-click the listener?

I believe we more or less have some implementations, however, the system has provided us with GestureDetectorthe class, if you are familiar with such realization, then the system will be able to choose for the same program, approval of the code will improve.

So today we have the opportunity to learn under:

GestureDetectorHow about support gesture is detected?

Here is a small edge content analysis.

We create the class instance, the need to interfaces OnGestureListener(used to monitor a variety of gestures) and implement it as a parameter passed into the constructor:

Explain the timing of each callback method (very easy to understand):

  • onDown: Finger press;

  • onShowPress: After the finger is pressed, not raised within 100 milliseconds, is not moved;

  • onSingleTapUp: Press the finger is not moved, and lift (can be identified as clicking) within 500 milliseconds;

  • onScroll: Drag your finger;

  • onLongPress: Long press (press the finger, not raised within 500 milliseconds, not moved);

  • onFling: After dragging your finger quickly let go (inertial scrolling);

In addition OnGestureListener, there are a OnDoubleTapListenersee be able to guess the name is used to monitor double-click the event:

explain:

  • onSingleTapConfirmed: I have confirmed that this is a click event, want to trigger double-click must continue to quickly double-tap the screen (ie: after lift a finger, did not wait 300 milliseconds finger pressed again);

  • onDoubleTap: Double-click trigger event (after lifting the finger is pressed again within 300 ms (Note: It is triggered when pressed again, and so it was not raised before the trigger))

  • onDoubleTapEvent: Trigger finger touch event after double click, including ACTION_DOWN, , ACTION_MOVE(Note:ACTION_UP After triggering long press, will not continue to receive the ACTION_MOVEevent, because the finger press process, the process does not require movement of the finger movement, which is directly ignore ACTION_MOVEthe event. also, the callback method after this, before triggering long press event, if the new finger is pressed, it is no longer identified as a double-click, it will not continue to call back to this method, it replaced onScroll). This approach with the above onDoubleTapmethod difference is that, onDoubleTapin the event of a double-click callback only once, and this method can callback times;

Well, it has a preliminary understanding later, take a look at it is how to detect these events.

1,onDown

Code for this class rarely, less than 800 lines (SDK28).

First look onDown method is when the callback (available at just the interface method CTRL + Clickmethod name corresponding to the location to locate specific call):

Super simple, listening to the ACTION_DOWNevents immediately pulled back.

2,onShowPress

Then take a look at onShowPressmethods (using just said method to locate):

It will GestureHandlerreceive whatfor the SHOW_PRESSfollowing message callbacks to see where the hair of the news:

emmm, also in receipt of ACTION_DOWNthe will to mHandler(i.e. GestureHandlersending) a message specifying a time, and this time is the pressing of the plus the time TAP_TIMEOUTduration can be seen TAP_TIMEOUTthe value is based on ViewConfigurationa getTapTimeoutmethod to obtain, and opening the one look:

Is 100 (ms), that is, when the finger is pressed, the delay if this task is not canceled within 100 milliseconds, then the onShowPressmethod will callback.

3,onSingleTapUp & onScroll

OK, now take a look at onSingleTapUp:

You can see that it is at ACTION_UPthe time the callback, the callback must meet three conditions, namely:

1.mIsDoubleTapping to false (ie, double-click the event is not triggered);

2.mInLongPress to false (ie long press event is not triggered);

3.mAlwaysInTapRegion为true;

mAlwaysInTapRegionWhat time it is true, what time is falseit:

There are three places assignment, namely:

1. ACTION_POINTER_DOWNWhen (another finger press) is false, that is to say, if only the first finger is pressed, there are 100 milliseconds new finger press, then when the lift will not trigger finger onSingleTapUp;

2. ACTION_DOWNwhen (only the first finger press) true;

3. ACTION_MOVEWhen, look else ifinside that if, it is judged distance(moving distance of the finger) is greater than slopSquare(the minimum trigger distance moved), and if so, will the callback onScrollmethod, and the mAlwaysInTapRegionset false, which indicates that, if the finger is pressed 100 within seconds, began to drag, then onSingleTapUpthe method is not callback;

You can also see when mAlwaysInTapRegionis set falseafter the next ACTION_MOVEtime comes, if there is no trigger double-click (ie, above mIsDoubleTapping为false) and the horizontal or vertical movement of the finger distance is not 0, then, it would have been the callback onScrollmethod.

Well, now onScroll, also spoke, turn onLongPressup.

4,onLongPress

Now onShowPressis the same method by means of Handlertiming mechanism to achieve message, it is received LONG_PRESSafter the message, calls the dispatchLongPressmethod, dispatchLongPressthe method will first mark mInLongPressastrue

(Note: This will affect when it comes to the top of the onSingleTapUpcallback, because onSingleTapUpcallback condition is the need mInLongPressto false(ie long press does not trigger))

Then callback onLongPressmethod.

So LONG_PRESSthe message when to send it?

Also at ACTION_DOWNthe time:

Before sending a message, it will first check if the monitor is turned on press events, as well as issuing press correction and did not perform the task once the cancellation.

Given time you can see down event time plus getLongPressTimeoutthe length method returns the default is 500 (ms), that is, when the finger is pressed half a second, onLongPressthe method will be called back, of course, provided that this task has not been cancel.

There are several situations can cause long been canceled by the callback tasks:

Within 500ms new finger is pressed;

Within 500ms triggered onScroll, namely finger movement over a specified distance;

Lift your finger within 500ms;

Within 500ms received the ACTION_CANCELevent (which ACTIONis generally derived from the parent container privately creation);

Take a look onFling:

5,onFling

We usually deal with inertial scrolling makes no difference, except that it will first determine whether the callback before sliding speed greater than the specified minimum speed, or not to carry out rolling rolling.

Well, finally we look at onSingleTapConfirmed, onDoubleTap, onDoubleTapEventrespectively, is how to deal with:

onSingleTapConfirmed、onDoubleTap、onDoubleTapEvent
  private class GestureHandler extends Handler {

      ......

      @Override
      public void handleMessage(Message msg) {
          switch (msg.what) {
              ......
              case TAP:
                  if (mDoubleTapListener != null) {
                      if (!mStillDown) {
                          mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
                      } else {
                          mDeferConfirmSingleTap = true;
                      }
                  }
                  break;
              ......
          }
      }
  }

  public boolean onTouchEvent(MotionEvent ev) {
      ......
      boolean handled = false;

      switch (action & MotionEvent.ACTION_MASK) {
          ......
          case MotionEvent.ACTION_DOWN:
              ......
              if (isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
                  mIsDoubleTapping = true;
                  handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
                  handled |= mDoubleTapListener.onDoubleTapEvent(ev);
              } else {
                  mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
              }
              mStillDown = true;
              ......
              break;

          case MotionEvent.ACTION_MOVE:
              if (mIsDoubleTapping) {
                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
              }
              ......
              break;

          case MotionEvent.ACTION_UP:
              mStillDown = false;
              if (mIsDoubleTapping) {
                    handled |= mDoubleTapListener.onDoubleTapEvent(ev);
              }
              ......
              if (mIsDoubleTapping) {
                  ......
              } else if (mInLongPress) {
                  ......
              } else if (mAlwaysInTapRegion) {
                  handled = mListener.onSingleTapUp(ev);
                  if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
                          mDoubleTapListener.onSingleTapConfirmed(ev);
                  }
              }
            ......
            break;
        ......
    }
    ......
    return handled;
}

First look at the onSingleTapConfirmedmethod, it has called in two places, namely:

GestureHandlerReceive the TAPmessage

Processing ACTION_UPevent

When the GestureHandlerreceived TAPmessage it checks whether the finger has been lifted ( !mStillDown), if already lifted, it would be called immediately, otherwise the mDeferConfirmSingleTapmark trueto indicate onSingleTapConfirmedthe method should ACTION_UPcallback, can be seen in the process ACTION_UP, if the finger not moved and did not press the trigger, it would determine mDeferConfirmSingleTapwhether true, yes, it would callback onSingleTapConfirmedmethod.

Then look at ACTION_DOWN, it calls the isConsideredDoubleTapmethod to determine whether the incident was identified by double-clicking, and if not, will be to GestureHandlersend a message latency (delay callback onSingleTapConfirmedmethod)

If so, will the mIsDoubleTappingmark true, followed by the callback onDoubleTapand onDoubleTapEvent. It can be seen in ACTION_MOVEand ACTION_UPwill also According mIsDoubleTappingto determine whether to continue the callback onDoubleTapEventmethod.

Well, now look, whether it is how recognized as a double-click to see isConsideredDoubleTapthe method:

First, the judge mAlwaysInBiggerTapRegion, if it is false, then the representatives of the other actions ( ACTION_MOVE, ) ACTION_CANCELinterrupted detect double-click events, it is returned directly false(ie, not identified by double-clicking) a.

Then determines the first and second press pressing time interval, it is asserted if more than 300 milliseconds is timed out, if less than 40 ms will be ignored (too fast).

Finally, many students may at first glance, do not see what kind of logic, a close look at a few times, you will know that this is actually the first time in the computing press and hold down the second coordinate distance, is calculated using two the distance between the point of formula (√ (x1 - x2) ² + (y1 - y2) ²).

At this point some students might ask:

Not even open square it? It is how the code is not it?

In fact, that slopSquare(that is, double-click can be identified as the maximum interval) during initialization, it has been squaring up, so there is no need to open the square.

emmm, then the isConsideredDoubleTapmethod last sentence means that, whether the coordinates of the touch event twice within a specified interval is the maximum interval range, and if so, is that it is the double-click.

Finally, attach my Android core technology learning syllabus, access to relevant content to play with my GitHub: https://github.com/Meng997998/AndroidJX

You take your time to invest in learning, it means that you can gain skills, have the opportunity to increase revenue.

Here to share my Android PDF Daquan learn to learn, learn this Android PDF Daquan really contain all aspects, and contains basic Java knowledge, the basis of Android, Android Advanced extension, and so on collection algorithm


Android-related learning content: concern I see personal introduction , or direct private letter I

My collection this study, can effectively help you grasp the knowledge points.

In short we are also here to help enhance learning advanced, but also saves you the time to learn online search data can also be shared with close friends studying together

Published 168 original articles · won praise 71 · views 20000 +

Guess you like

Origin blog.csdn.net/Aerfa789/article/details/105203310