Android Application Development-full solution to custom View touch-related tools

Source: Internet
Author: User

Android Application Development-full solution to custom View touch-related tools
Background

Recently, there have been some chaos, various things, and various intersections. Fortunately, there is a bit more self-motivated, so we will continue to sort out the core knowledge of the custom series. As mentioned in the previous blog on custom controls, we will not teach you how to take things, but how to teach them to fish. If you like to take things, sorry, Please bypass it. If you like fish, continue.

We have already described several things related to custom views. You can go back to my previous blog, such as event processing, coordinate system, and tool class. Below we will continue to add some commonly used custom control tool classes.

ViewConfiguration basic parameter tool

The ViewConfiguration class mainly provides some standard constants used by custom controls, such as the size, sliding distance, and sensitivity, you can use a custom control directly to avoid testing it yourself. The following is a look at the source code of this class. You can directly refer to it when using it. There is no special logic, so no source code analysis is performed. As follows:

Public class ViewConfiguration {...... // not recommended. ViewConfiguration is recommended. get (Context) get instance public ViewConfiguration () {} public static ViewConfiguration get (Context context) {} // not recommended. getScaledScrollBarSize () is recommended; obtain the width of the horizontal scroll bar or the height of the vertical scroll bar. public static int getScrollBarSize () {} public int getScaledScrollBarSize () {}// duration of the disappearance of the scroll bar. public static int getScrollBarFadeDuration () {} // Delay Time for the disappearance of the scroll bar public static int getscrolldefadelay () {} // not recommended. We recommend that you replace getScaledFadingEdgeLength (); remove the length of the edge public static int getFadingEdgeLength () {} public int getScaledFadingEdgeLength () {}// duration of the press public static int getPressedStateDuration () {} // The time required to press and hold the status to change to long press: public static int getLongPressTimeout () {} // press the key again to determine the time public static int getKeyRepeatTimeout () {} // The time when duplicate keys are delayed. public static int getKeyRepeatDelay () {} // you can check whether the key is clicked or rolled. If the key is not moved within the time range, the key is clicked, otherwise, it is rolling public static int getTapTimeout () {}// the click is not completed within this time period, so it is considered as a click event public static int getJumpTapTimeout () {} // obtain the double-click interval. In this period, double-click. Otherwise, the public static int getDoubleTapTimeout () {} // is not recommended. We recommend that you use getScaledEdgeSlop () instead; judge whether the sliding event is public static int getEdgeSlop () {} public int getScaledEdgeSlop () {}// not recommended. We recommend that you use getScaledTouchSlop () instead, the mobile phone must be larger than this distance to move the public static int getTouchSlop () {} public int getScaledTouchSlop () {}// judgment of the touch edge padding area public int getScaledPagingTouchSlop () {} // not recommended. We recommend that you replace getScaledDoubleTapSlop (); Determine whether to double-click the public static int getDoubleTapSlop () {} public int getScaledDoubleTapSlop () {} // not recommended, getScaledWindowTouchSlop () is recommended; public static int getWindowTouchSlop () {} public int getScaledWindowTouchSlop () {}// not recommended. getScaledMinimumFlingVelocity () is recommended; get the minimum sliding speed. Calculate the public static int getMinimumFlingVelocity () {} public int getScaledMinimumFlingVelocity () {}// this is not recommended. We recommend that you use getScaledMaximumFlingVelocity () instead; get the maximum sliding speed. Calculate the public static int getMaximumFlingVelocity () {} public int getScaledMaximumFlingVelocity () {}// this is not recommended. We recommend that you use getScaledMaximumDrawingCacheSize () instead; obtain the maximum image cache size, in the unit of bytes public static int getMaximumDrawingCacheSize () {} public int getScaledMaximumDrawingCacheSize (){}......}

With the above tool class, we can easily determine critical values when using custom controls to process sliding gestures and other judgments, we don't need to test and define an approximate value instead.

Note:ViewConfiguration also has a compatibility class ViewConfigurationCompat in the support package. Pay attention to this when using ViewConfiguration.

Scroroller enhanced overscroroller rebound Tool

A previous blog mentioned Scroller's source code analysis. In fact, Scroller appeared in API 1, and the Scroller enhanced version OverScroller mentioned here appeared in API 9, therefore, the function designation is more powerful than the previous scroroller and supports the rebound effect (for different Rebound Effects, We can customize different animation interpolation devices ), however, the principle is basically the same as the Scroller source code analyzed previously, so we will not analyze the OverScroller source code here, but will explain the differences between him and Scroller. Let's take a look at it.

OverScroller methods based on the Scroller class:

Method Description
IsOverScrolled () Returns whether the current position is valid or exceeds the scroll boundary.
SpringBack (int startX, int startY, int minX, int maxX, int minY, int maxY) Call this method when you want to roll back. The rollback range is within the valid coordinate range.
Fling (int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, int overX, int overY) The same as Scroller, but the last two parameters mean that fling scrolling exceeds the valid value range.
Policyhorizontaledgereached (int startX, int finalX, int overX) Whether the horizontal scroll of the notification reaches the boundary.
Policyverticaledgereached (int startY, int finalY, int overY) Same as above.

For the basic use process of Scroller, refer to my previous blog Scroller source code analysis and ViewDragHelper source code analysis. If you need to understand it in depth, you can see the implementation of the official ScrollView, and OverScroller is fully used.

Note:Scroller (OverScroller) also has a compatible class ScrollerCompat in the support compatibility package. Please pay attention to it when using it.

VelocityTracker gesture SPEED TOOL

VelocityTracker is mainly used to track the speed of touch screen events (Flinging and other Gestures gesture events. After obtaining the instance, we can use computeCurrentVelocity (int) to initialize the rate unit, and then add the MotionEvent to the VelocityTracker instance through addMovement (MotionEvent, then, you can use getXVelocity () or getXVelocity () to obtain the horizontal and vertical rate as needed.

The following describes related APIs (many methods of VelocityTracker are implemented by native ):

Public final class VelocityTracker {// obtain the static public VelocityTracker obtain () {} public static VelocityTracker obtain (String strategy) {} // you do not need to use it after collection, the system assigns this object to other requestor public void recycle () {}// clears it back to the initial state, computeCurrentVelocity is reset public void clear () {}// Add the event to the VelocityTracker class instance. public void addMovement (MotionEvent event) {}// unitis indicates the Basic time unit of the rate, 1 indicates the number of pixels in motion per millisecond. public void computeCurrentVelocity (int units) {}// same as above. floatVelocity indicates the maximum rate, if the maximum value is exceeded, the maximum value public void computeCurrentVelocity (int units, float maxVelocity) {}// gets the xy direction rate public float getXVelocity () {} public float getYVelocity () {}// get the xy rate. The id is the pointid public float getXVelocity (int id) of the event {} public float getYVelocity (int id ){}}

With the above gesture rate detection tool class, let's take a look at some of his general templates:

VelocityTracker mVelocityTracker = null;  @Override    public boolean onTouchEvent(MotionEvent event){        int action = event.getAction();        switch(action){        case MotionEvent.ACTION_DOWN:            if(mVelocityTracker == null){            mVelocityTracker = VelocityTracker.obtain();            }else{            mVelocityTracker.clear();            }            mVelocityTracker.addMovement(event);            break;        case MotionEvent.ACTION_MOVE:            mVelocityTracker.addMovement(event);            mVelocityTracker.computeCurrentVelocity(1000);         Log.i("X = "+mVelocityTracker.getXVelocity());            Log.i("Y = "+mVelocityTracker.getYVelocity());            break;        case MotionEvent.ACTION_UP:        case MotionEvent.ACTION_CANCEL:            mVelocityTracker.recycle();            break;        }        return true;    } 

I will introduce the speed detection knowledge here, nothing new.

GestureDetector gesture tool class

In addition to processing a bunch of complex gestures through onTouchEvent (), Android provides us with a ready-made and convenient way, that is, GestureDetector gesture listening class, as shown below:

Public class GestureDetector {public interface OnGestureListener {// trigger boolean onDown (MotionEvent e) When ACTION_DOWN; // trigger when ACTION_DOWN has not been swiped for a while, onDown-> onShowPress-> onLongPress void onShowPress (MotionEvent e); // The boolean onSingleTapUp (MotionEvent e) is triggered when ACTION_UP is not slide (onScroll) and the onLongPress is not followed by ACTION_UP ); // trigger boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) in real time when sliding; // trigger void onLongPress (MotionEvent e) on time when ACTION_DOWN is long ); // trigger when the touch slides at a certain distance and then float ACTION_UP. The post parameter is speed boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY );} public interface OnDoubleTapListener {// No sliding (onScroll) after ACTION_DOWN and no long-pressed (onLongPress) after ACTION_UP triggers boolean onSingleTapConfirmed (MotionEvent e ); // trigger boolean onDoubleTap (MotionEvent e) when double-clicking the second ACTION_DOWN; // double-clicking the second ACTION_DOWN and ACTION_UP will trigger, e. getAction () distinguishes between boolean onDoubleTapEvent (MotionEvent e);} public interface OnContextClickListener {// context click trigger, which is related to View # onGenericMotionEvent (MotionEvent, boolean onContextClick (MotionEvent e);} public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener, OnContextClickListener {...... // default implementation of all OnGestureListener, OnDoubleTapListener, and OnContextClickListener interfaces ......} // recommended construction methods @ Deprecated public GestureDetector (OnGestureListener listener, Handler handler) {}@ Deprecated public GestureDetector (OnGestureListener listener) {} public Context (context Context context, onGestureListener listener) {} public GestureDetector (Context context, OnGestureListener listener, Handler handler) {} public GestureDetector (Context context, OnGestureListener listener, Handler handler, boolean unused) {} // other two types of callback interface settings. OnGestureListener must process the public void listener (OnDoubleTapListener onDoubleTapListener) {} public void setContextClickListener (OnContextClickListener onContextClickListener) {}// some processing and judgment methods: public void setIsLongpressEnabled (boolean isLongpressEnabled) {} public boolean isLongpressEnabled () {} public boolean onTouchEvent (MotionEvent ev) {} public boolean onGenericMotionEvent (MotionEvent ev) {}}

With the introduction to the basic APIs of the above GestureDetector gesture tool class, we can use all kinds of tools without any special introduction.

Note:In fact, there are also GestureOverlayView gestures such as Gesture to create recognition classes, which are not described here as an extension.

View and ViewGroup touch event Summary

For source code analysis on the transmission mechanism of View touch screen events, refer to the blog I wrote earlier. Since this article is a summary, it only gives a conclusion. For relevant analysis, see the previous blog.

Touch event transfer source Activity:

The dispatchTouchEvent () method of the Activity transmits the event to its root layout ViewGroup (that is, the dispatchTouchEvent () method of the root layout ViewGroup is called. This method handles the event as follows:

If neither the root layout ViewGroup nor its internal child layout controls are processed (the dispatchTouchEvent () method of the root layout ViewGroup returns false), the Activity's onTouchEvent () method is called; if the onTouchEvent () method of the Activity is still not processed (false is returned), the event processing ends.

If true is returned by the dispatchTouchEvent () method of the ViewGroup in the root layout, this event is processed in the root layout and the onTouchEvent () of the Activity is no longer called () method (because the Activity does not have a parent control and the OnTouchListener cannot be set for the touch listener, there is no onInterceptTouchEvent () method ).

View-level processing of touch event transfer:

Here, the so-called View level refers to the View that does not contain a child control (the smallest control unit). When the parent ViewGroup of the View triggers the dispatchTouchEvent () method of the View, as this View does not have child controls that can be distributed, the event can only be scheduled by itself. The test scheduling is as follows:

If the View registers OnTouchListener, The onTouch () method of OnTouchListener is called first. If the onTouch () method returns false, the onTouchEvent () method of the View is redeployed. If onTouch () if the method returns true, the View's dispatchTouchEvent () method returns true directly.

If the View does not register an OnTouchListener, The onTouchEvent () method of the View is called directly. The return value of true and false determines the return value of the dispatchTouchEvent () method of the View.

ViewGroup-level processing for passing touch events:

The dispatchTouchEvent () method of ViewGroup is called by its parent layout (parent ViewGroup or Activity). The dispatchTouchEvent () method of the current ViewGroup () the main task of this method is to dispatch an event (dispatch the dispatchTouchEvent () of the Child Control) for the child control and return the event processing status to the parent layout.

However, before the dispatchTouchEvent () method of the current ViewGroup sends an event to the Child control, we can use our onInterceptTouchEvent () method in the current ViewGroup () method to Determine whether to intercept the touch event (the onInterceptTouchEvent () of the current ViewGroup returns true, instead of being passed to its own child control, but the current ViewGroup handles it by itself, and then tells the parent control the processing result; if false is returned, the system does not intercept the event. If the dispatchTouchEvent () method of the subcontrol returns false, the ViewGroup tries to process the event by itself, and then tell the parent layout to handle the result ).

Complete Event process processing:

Based on the event processing process from Activity to root ViewGroup to ViewGroup in the middle, and then to View, we should pay attention to the following points during the transfer process:

A complete event trigger can be divided into ACTION_DOWN-> [ACTION_MOVE]-> ACTION_UP. When we press the finger to dispatch the ACTION_DOWN event, if the onTouch () or onTouchEvent () method of the View or ViewGroup at the current level returns false, the onTouch () of the View or ViewGroup at the current level is () or the onTouchEvent () method will no longer receive other events until the next new touch event (ACTION_DOWN) starts.

In a complete event transfer (ACTION_DOWN-> [ACTION_MOVE]-> ACTION_UP) process, as long as the onInterceptTouchEvent () of the current ViewGroup () if the method returns true once, the current ViewGroup will intercept all subsequent triggering events passed by this event, and these subsequent triggering events will not trigger the onInterceptTouchEvent () of the current ViewGroup () method (until the next ACTION_DOWN is approaching), and an ACTION_CANCEL event is passed to the sublayout of the previously handled event. If the onInterceptTouchEvent () method of the current ViewGroup returns false, each event passed this time will trigger the onInterceptTouchEvent () method of the current ViewGroup temporarily.

Only ViewGroup has the onInterceptTouchEvent () method, because the smallest unit of View does not have the ability to dispatch events again, it will only directly call its own onTouch () and onTouchEvent () methods.

When the parent ViewGroup intercepts the current transfer event, the internal sub-Layout View or ViewGroup cannot receive the dispatch event again; however, we have a way to prevent the parent ViewGroup from intercepting the passed events (getParent (). requestDisallowInterceptTouchEvent (true);). Once the child Layout View or ViewGroup receives the touch event and calls this method, the parent ViewGroup will no longer call its own onInterceptTouchEvent () method, getParent () again after the event is processed (). requestDisallowInterceptTouchEvent (false.

The Touch event transfer of this View is summarized. Remember these rules when using the View. We also recommend that you View the source code.

Summary

As you can see, there are almost so many things related to the basic touch of custom controls, with the above things, you can basically turn to the Android custom control to handle the pain points related to the touch. You don't have to worry about it any more.

This blog post does not include any examples, because it is a summative article. The summary of this article is basically an in-depth analysis article in my previous blog, so if you are interested, you can refer to my previous blog. Thank you.

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.