Event distribution mechanism in Android (under)--view event handling

Source: Internet
Author: User

Overview

In the previous article on the event distribution mechanism (above) in Android,--viewgroup's event distribution was analyzed in detail for ViewGroup event distribution. In the last viewgroup of the article, the Dispatchtouchevent method calls the Dispatchtransformedtouchevent method to successfully pass the event to the child view of ViewGroup. and is processed by the child view. So now it's time to analyze how the view receives the event and how it is handled.

Event handling for view

For the view described here, it is the parent class of ViewGroup and does not contain any child elements. This also means that view cannot distribute the event down again, so there is no Onintercepttouchevent method in view and no interception action is made on the event. What it does is handle the events that are received. Let's take a look at how the view handles the event.
Since ViewGroup the event to the dispatchtouchevent side of the view. So first here, let's take a look at what's going on in Dispatchtouchevent.

 PublicBooleandispatchtouchevent(motioneventEvent) {    ......if(Onfiltertoucheventforsecurity (Event)) {//noinspection simplifiableifstatementListenerinfo li = mlistenerinfo;if(Li! =NULL&& Li.montouchlistener! =NULL&& (Mviewflags & enabled_mask) = = ENABLED && Li.mOnTouchListener.onTouch ( This,Event) {result =true; }if(!result && ontouchevent (Event) {result =true; }    }    ......returnResult;}

The core part of event handling in the view's Dispatchtouchevent method is reflected in the code above. The Onfiltertoucheventforsecurity method indicates whether the view currently receiving the event is cloaked, and the view is obscured to indicate that the current view is not at the top and that the view is covered by another view. If the current view is obscured, the view does not process the event.

public   Interface  Ontouchlistener {boolean onTouch (View V, motionevent event );} public  void  setontouchlistener  (Ontouchlistener L) {Getlistenerinfo (). Montouchlistener = l;} Listenerinfo Getlistenerinfo () {if  (mlistenerinfo! =     Null ) {return  mlistenerinfo;    } mlistenerinfo = new  listenerinfo (); return  mlistenerinfo;}  

In conjunction with the preceding paragraph of code can be seen, after setting Ontouchlistener through the Setontouchlistener method, if the current view is in the available state, then the condition Li! = null && Li.montouchlistener!=null && (mviewflags & enabled_mask) = = ENABLED must be true. At this point the program will callback the Ontouch method in Ontouchlistener, and if it returns true in the Ontouch method, it will not execute the Ontouchevent method of the view. From here we can see that once the Ontouchlistener is set, the Ontouchlistener priority is higher than ontouchevent.
It is important to note that after Ontouchlistener is set in the program, the return value for Ontouch in Ontouchlistener does not represent the value returned by the Dispatchtouchevent method in view. When the Ontouch method returns True, it indicates that the event was successfully consumed by the current view, when result is set to true and no longer executes ontouchevent, so dispatchtouchevent returns True. However, once you return False in the Ontouch method. The Ontouchevent method is called and returns True if the event is successfully processed by ontouchevent and returns True,result is still set to True,dispatchtouchevent. The
follows the Ontouchevent method of entering view. The content of the Ontouchevent method is much more, in this section to view.

if ((viewFlags & ENABLED_MASK) == DISABLED) {    if0) {        setPressed(false);    }    // A disabled view that is clickable still consumes the touch    // events, it just doesn‘t respond to them.    return (((viewFlags & CLICKABLE) == CLICKABLE            || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)            || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE);}

Here you can see that for a view that is not available, if some of their click events are available, they will still be able to consume the event successfully, except that it will not respond to the event. These clicks between views are not available by default, but they do not have the same default values for different view. For example, the Click event in ImageView is still unavailable, but clicking on the event in the button is available. Of course, if the listener events are set manually for them, then these listener events will automatically be set to the available state. From the following source code can be seen.

 Public void Setonclicklistener(@Nullable onclicklistener L) {if(!isclickable ()) {setclickable (true); } getlistenerinfo (). Monclicklistener = l;} Public void Setonlongclicklistener(@Nullable onlongclicklistener L) {if(!islongclickable ()) {setlongclickable (true); } getlistenerinfo (). Monlongclicklistener = l;} Public void Setoncontextclicklistener(@Nullable oncontextclicklistener L) {if(!iscontextclickable ()) {setcontextclickable (true); } getlistenerinfo (). Moncontextclicklistener = l;}

Next look at the code inside the ontouchevent.

ifnull) {    if (mTouchDelegate.onTouchEvent(event)) {        returntrue;    }}

This first determines whether the agent is set on the event, and if a proxy is set on the event, the Touchdelegate ontouchevent method is executed. Mtouchdelegate default value is NULL, you can set the proxy through the view's Settouchdelegate method. For touchdelegate in the subsequent articles in the detailed analysis, here is not too much description.
Finally, look at how the view handles the event, the whole process of receiving the event is more complex, here from the macro to look at the overall processing mechanism.

if(((ViewFlags&clickable)==Clickable||(ViewFlags&long_clickable)==long_clickable)||(ViewFlags&context_clickable)==context_clickable) {switch (action) { CaseMotionevent.ACTION_UP:......                if(!Mhasperformedlongpress&& !Mignorenextupevent) {//This was a tap, so remove the Longpress checkRemovelongpresscallback ();//Only perform take click on actions if we were in the pressed state                    if(!Focustaken) {//Use a Runnable and post this rather than calling                        //PerformClick directly. This lets other visual state                        //Of the view update before click Actions Start.                        if(Mperformclick== NULL) {Mperformclick= NewPerformClick (); }if(!Post (Mperformclick)) {PerformClick (); }                    }                }......Break......}return true;}

If the view's click events are available, the events are processed and true. When a sequence of events is completed, call the PerformClick method, and see the PerformClick method below.

public   Boolean  performclick  () {final  boolean  result; final     Listenerinfo li = mlistenerinfo; if  (Li! = null  && li.monclicklistener! = null        ) {playsoundeffect (Soundeffectconstants.click);        Li.mOnClickListener.onClick (this );    result = true ;    } else  {result = false ;    } sendaccessibilityevent (accessibilityevent.type_view_clicked); return  result;}  

As you can see from the code above, if we set the Onclicklistener, we call its OnClick method. From here we can see that the OnClick event for the view is called at the end, and the priority of the onclick is the lowest.

Summary

Here is a summary of the event handling of the view. After you distribute the event to view in ViewGroup. The event is handled in view through the Ontouchlistener Ontouch and the ontouchevent in view. For the Ontouch method, the view is provided to the user, allowing the user to handle the touch events themselves, while the ontouchevent is the interface that the Android system implements itself. If the user sets the Ontouchlistener,android system, the Ontouchlistener Ontouch method is called first. If True is returned in the Ontouch method, the view's Ontouchevent method is not executed. Ontouchevent is executed only if False is returned in Ontouch.

Event distribution mechanism in Android (under)--view event handling

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.