TouchEvent Touch event mechanism in Android

Source: Internet
Author: User
Tags event listener

Touch event TouchEvent is triggered when our fingers are clicked or slid on the Android screen. In the app, ViewGroup and view exist in multiple levels of nesting, in the outermost is activity, the most inner view, between activity and view is some viewgroup. To simplify the discussion, we assume that there is only one viewgroup in an activity, and that there is only one view in the ViewGroup. When we touch the UI of the view with our fingers, we create a touch event touchevent, as shown in the general process:

First, the outermost activity receives the event, triggering the execution of the activity's dispatchtouchevent, in which the activity invokes the execution of the internal ViewGroup Dispatchtouchevent method, In the Dispatchtouchevent method of ViewGroup, the execution of the Dispatchtouchevent method of the most inner view is called, The Ontouchevent method of the view may be executed in the Dispatchtouchevent method of the view, and then ViewGroup is also possible to execute the Ontouchevent method of ViewGroup. It is then possible for the activity to perform the Ontouchevent method of activity.

is a streamlined main flow chart, a total of two main lines:

    1. The first line is, from the activity--viewgroup, View, from the outside to call the Dispatchtouchevent method, Android will sequentially pass the Motionevent parameter to the method. Dispatchtouchevent's role is to pass the touch event, which embodies the process of passing a touch event from the outside to the outside, Dispatchtouchevent is the entry for each touch event.

    2. The second main line, from view-ViewGroup, Activity, calls the Ontouchevent method from inside out, and Android passes the Motionevent parameter to the method sequentially. The role of ontouchevent is to handle touch events, which embody the process of handling touch events from inside to outside.

Both Dispatchtouchevent and ontouchevent receive a motionevent type of parameter, motionevent encapsulates the data information of the touch event, including the type of touch event and coordinate location, as described in the blog Motionevent in Android. " Both Dispatchtouchevent and Ontouchevent have a Boolean return value that, if true, indicates that the current object has handled the touch event, or false to indicate that the current object is not processing the touch event.

The following is a detailed description of the activity, ViewGroup, view of the event distribution, processing process.

Activity
  • Dispatchtouchevent
    All touch events generated by touch operations on the UI first trigger the execution of the Dispatchtouchevent method in the activity, and the source code is as follows:

    publicbooleandispatchTouchEvent(MotionEvent ev) {    if (ev.getAction() == MotionEvent.ACTION_DOWN) {        onUserInteraction();    }    if (getWindow().superDispatchTouchEvent(ev)) {        returntrue;    }    return onTouchEvent(ev);}

    The key to the above approach is that the activity will first get the current Window object through the GetWindow () method, and then call the window's Superdispatchtouchevent method, in fact, GetWindow () Returns an instance of the Phonewindow type, which calls the Phonewindow Superdispatchtouchevent method, with the source code as follows:

    @OverridepublicsuperDispatchTouchEventevent) {    return mDecor.superDispatchTouchEvent(event);}

    Mdecor is a variable of type Decorview in Phonewindow, Decorview represents the top view of the current window and can be viewed as a root view. As seen from the above code, the following will execute the Decorview superdispatchtouchevent method, the source code is as follows:

    publicsuperDispatchTouchEventevent) {    return super.dispatchTouchEvent(event);}

    In fact Dectorview inherits from Framelayout, so Dectorview indirectly inherits from ViewGroup, so Dectorview executes its parent viewgroup corresponding Dispatchtouchevent method. In this method, Dectorview will find the child node of its touch, in fact its child node is also a viewgroup, and then execute the ViewGroup dispatchtouchevent method, This allows the touch event parameter motionevent to be transferred from the activity to the Decorview sub-viewgroup. We will discuss the execution logic in the Dispatchtouchevent method in ViewGroup, which is not covered here.

    The above describes the process of passing touch events from activity to viewgroup with the Superdispatchtouchevent and Dispatchtouchevent methods, both of which return a Boolean type of argument. If true, indicates that the touch event is processed, whereas the touch event is not processed. If we look at the source code of Dispatchtouchevent in activity above, we will find that if Phonewindow's superdispatchtouchevent returns True, The Dispatchtouchevent method of the activity also returns true directly, indicating that the touch event is handled by the window, so the Ontouchevent method of the subsequent activity is not executed. The activity calls the Ontouchevent method to handle the event only if window does not handle the touch event.

  • Ontouchevent
    The source code for Ontouchevent is as follows:

    publiconTouchEventevent) {    if (mWindow.shouldCloseOnTouch(thisevent)) {        finish();        returntrue;    }    returnfalse;}

    The activity executes its own ontouchevent to handle touch events only if the touch event is not processed by any view or viewgroup. A typical case is that the current touch point is outside the window, so that all the view in the window will not receive more processing of the touch event, we can override the method to implement some of our own logic to handle this situation. Returns true if we have processed it, otherwise false is returned. Its default implementation basically always returns false.

ViewGroup
  • Dispatchtouchevent
    When the activity receives the touch event, it will call ViewGroup's Dispatchtouchevent method through Dectorview, because the method's source code is too long, here do not paste the source, click here to view its source code. The main logic in this method is mainly described here. The Dispatchtouchevent method is the entry that viewgroup the touch event.

    A touchtarget type member variable mfirsttouchtarget is defined in ViewGroup to hold the child view that handles the touch event in the current ViewGroup.

    First, the Dispatchtouchevent method calls its own Onintercepttouchevent method, Onintercepttouchevent is used to intercept the ViewGroup to pass the touch event to its child view, If the method returns True, the ViewGroup should intercept the touch event, or false to indicate that ViewGroup should not intercept the touch event and that the touch event should be passed to the child view. A Boolean type of handled variable is also defined in the Dispathtouchevent method to hold the return value of the Dispathtouchevent method, and if True indicates that the touch event was handled by the current viewgroup. Conversely, it means that it has not been processed.

    Then, only when Onintercepttouchevent returns False,viewgroup will it traverse its child view in turn, It will determine whether the coordinates of the touch event carried by the motionevent fall within the range of the child view by calling the Istransformedtouchpointinview method, and if the coordinates of the touch event fall exactly within the sub-view range, It means that we touch the sub view in the current ViewGroup so that ViewGroup will pass the coordinates of the touch event and the child view to the Dispatchtransformedtouchevent method, Within the method, the Dispatchtouchevent method of the child view is called, and its return value indicates whether the touch event was handled by the view, and if Dispatchtransformedtouchevent returns True, the child view handles the touch event This viewgroup binds the mfirsttouchtarget to the child view by calling the Addtouchtarget method, and the variable alreadydispatchedtonewtouchtarget is also set to true. Indicates that a touch event has been processed by a child view. Once a child view handles the touch event, ViewGroup jumps out of the for loop and no longer iterates over the other child view.

    After the for loop of the child view is passed, if no child view handles the touch event, then Mfirsttouchtarget is still null. At this point ViewGroup will pass NULL as the child parameter into the Dispatchtransformedtouchevent method, The method calls the Super.dispatchtouchevent method, because ViewGroup inherits from view, where it is equivalent to executing the Dispatchtouchevent method in the view class, so it is possible to perform viewgroup inherited from view ont Ouchevent method. The return value of the dispatchtransformedtouchevent is used as the value of the local variable handled. The Dispatchtouchevent method in the view class is described in detail below.

    After a for loop of a pair view is passed, if a child view is found to handle the touch event, then Alreadydispatchedtonewtouchtarget is true, and the local variable handled is set to true. This means that as long as a child view handles the touch event, the current ViewGroup also handles the touch event, and in this case ViewGroup does not invoke the Dispatchtouchevent method inherited from view. This will not trigger the execution of the ViewGroup ontouchevent method.

  • Onintercepttouchevent
    Previously mentioned that Onintercepttouchevent is used to intercept viewgroup to pass touch events to Child view, the default implementation in ViewGroup always returns false, which means no interception. We can override this method to implement our own touch event interception logic.

  • Dispatchtransformedtouchevent
    Click here to view the source code, and its main logic is as follows:

    Private Boolean dispatchtransformedtouchevent(Motionevent event,BooleanCancel, View child,intDesiredpointeridbits) {Final BooleanHandledFinalMotionevent transformedevent; ......//Perform any necessary transformations and dispatch.    if(Child = =NULL) {handled =Super. Dispatchtouchevent (Transformedevent); }Else{Final floatOffsetX = Mscrollx-child.mleft;Final floatOffsetY = Mscrolly-child.mtop; Transformedevent.offsetlocation (OffsetX, OffsetY);if(! Child.hasidentitymatrix ())        {Transformedevent.transform (Child.getinversematrix ());    } handled = Child.dispatchtouchevent (transformedevent); }//Done.Transformedevent.recycle ();returnhandled;}

    The main purpose of this method is to convert the coordinates of x and y in motionevent to the coordinates in the coordinate system of the view specified by the passed child variable, and transformedevent represents the motionevent that has completed the transformation of the specified coordinate system. If the passed-in child parameter is NULL, indicating that the current viewgroup is passed in, the Super.dispatchtouchevent (transformedevent) is called directly, This allows ViewGroup to invoke the Dispatchtouchevent method in the parent view, if the passed-in child parameter is not NULL, representing a sub-view of the current ViewGroup passed in. Then the Child.dispatchtouchevent (transformedevent) is called to pass the touch event from ViewGroup to the child view. We will introduce the implementation logic of view dispatchtouchevent below.

  • Ontouchevent
    ViewGroup's ontouchevent inherits from the View Ontouchevent method, ViewGroup is not rewritten, we will introduce the implementation logic of the Ontouchevent method of view below.

View
  • Dispatchtouchevent
    Click here to view the source code, its main logic is as follows:

     PublicBooleandispatchtouchevent(motioneventEvent) {... boolean result =false; ......if(Onfiltertoucheventforsecurity (Event)) {//noinspection simplifiableifstatementListenerinfo li = mlistenerinfo;//If Ontouchlistener is set, the Ontouch method of Ontouchlistener is executed here        if(Li! =NULL&& Li.montouchlistener! =NULL&& (Mviewflags & enabled_mask) = = ENABLED && Li.mOnTouchListener.onTouch ( This,Event)) {//If Ontouchlistener's Ontouch method returns True, it means that the touch event is processed and result is set to Trueresult =true; }//If the touch event is not ontouchlistener processed, then the Ontouchevent method of the view will be executed        if(!result && ontouchevent (Event)) {//If Ontouchevent returns True, the touch event is handled by the view, and result is set to Trueresult =true; }    }    ......returnResult;}

    Dispatchtouchevent is the entrance to the view handle touch event. In this method, the view first looks at whether it has set the Ontouchlistener, and if it has been set to call Ontouchlistener's Ontouch method, if it returns true, the touch event is processed and result is set to true. If the touch event is not handled by Ontouchlistener, then the Ontouchevent method of the view is executed, and if Ontouchevent returns True, the touch event is handled by the view, and result is set to true.

    As can be seen, in the Dispatchtouchevent method is the first execution of the Ontouchlistener Ontouch method, once it returns true, will not invoke the view itself Ontouchevent method, Only Ontouchlistener does not handle touch events to execute the view's Ontouchevent method later.

  • Ontouchevent
    Click here to view the source code, in the View.ontouchevent () method, if view registers an event listener such as click or Long_click, then the registered event listener will be allowed to handle the touch event so that Ontouchevent returns True. Depending on the action, different processing is performed, such as ACTION_UP, which executes the PerformClick () method, which triggers the execution of the Onclicklistener.onclick ().
    If view does not register any event listeners such as Click or Long_click, then Ontouchevent returns False, indicating that Ontouchevent has not done any processing on the incoming touch event motionevent.

Summarize

We can see from the above activity, the ViewGroup, the view each level touches the touch event processing process to discover, Android each level to handle the touch event to start from the Dispatchtouchevent method, First call the next level of the Dispatchtouchevent method, the touch event is passed to the next level, if the next level of touch event processing, you can think that this level is also the touch event processing, then this level will not touch event only need to do other special processing If the touch event is not processed at the next level, that is, the next level of the Dispatchtouchevent method returns False, then the Ontouchevent method at this level is called to handle the touch event.

More of my blog posts can be found in my Android blog summary, I hope this article to you understand the touch event mechanism in Android has helped!

TouchEvent Touch event mechanism in Android

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.