Android View event Distribution mechanism grooming

Source: Internet
Author: User

on view

The event distribution mechanism of the view has been very faint, and today it is here to comb

MyView

First inherit the view class and customize a myview. And when initializing the view class can be clicked, here from the view Click event Distribution point of view, so do not consider drawing, measuring the implementation of related methods.

     Public  class MyView extends View {String TAG ="Activity"; Public MyView(Context context) {Super(context);    Init (); } Public MyView(context context, AttributeSet attrs) {Super(context, attrs);    Init (); } Public MyView(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr);    Init (); }Private void Init() {LOG.E (TAG,"The View clickable is"+ isclickable ()); }}

Place the entire myview in the layout file and look at the log logs.

    <engineer.test.MyView        android:id="@+id/myview"        android:layout_width="150dp"        android:layout_height="150dp"        android:layout_centerInParent="true"        android:background="#ff00ff" />

As you can see, the view class is not clickable by default.

Monitor the touch event of a view

This first clarifies the values corresponding to the events in the Motionevent

    publicstaticfinalint0;    publicstaticfinalint1;    publicstaticfinalint2

Set Ontouchlistener for MyView and print the event log

    myView = (MyView) findViewById(R.id.myview);    myView.setOnTouchListener(new View.OnTouchListener() {            @Override            publiconTouchevent) {                "myview_onTouch---->"+event.getAction());                returnfalse;            }        });

Click MyView to see the log:

As you can see, only the Action_down event has occurred, and the Action_up event has not occurred, which is why?

Set Onclicklistener for MyView and print the log

myView.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Log.e(TAG, "the View clickable is " + myView.isClickable());            Log.e(TAG, "myview_onClick");        }    });

Click MyView to see the log:

As you can see, after setting Clicklistener:

    • MyView directly from a non-clickable control into a clickable control, Isclickable returns True.
    • Both the Action_down and action_up events occurred.
    • The touch event occurs before the Click event.

We see that the Ontouch method of Touchlistener has a return value, and the default return is False, we change it to true, and then click MyView to see the log:

As you can see, after clicking MyView multiple times, the click Method does not execute, that is, when the Ontouch event returns True, it is equivalent to shielding the click event from occurring

View Source Analysis

Based on the series of results and questions obtained above, let's take a look at the two methods Dispatchtouchevent and ontouchevent about event distribution in view.

First look at Dispatchtouchevent, because the first thing to do is this method

API comments

/**
* Pass the touch screen motion event to the target view, or this
* View if it is the target.
*
* @param event The motion event to be dispatched.
*
* @return True If the event is handled by the view, false otherwise.
*/

As you can see from the note, this method returns true if the current view is handling this event.

Dispatchtouchevent Source (capture main content)
  PublicBooleandispatchtouchevent(motioneventEvent) {Boolean result =false;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 }

As you can see, the default return value here is Result=false

    • First, the Onfiltertoucheventforsecurity method detects whether the Click event actually occurs on the current view, and if so, the view handles the current click event, otherwise it returns false without handling the event.
    • Next, when the view's touchlistener is not NULL, and the view is enable, and the Touchlistener Ontouch method returns True, Result=true, The Ontouchevent method in the following if statement does not execute so that the OnClick method is not called, which is consistent with the result of the last Test.

However , under normal circumstances, the Ontouch method returns false , so it is executed into the following ontouchevent method.

Ontouchevent Source code (interception of primary logic)
  Public Boolean ontouchevent(Motionevent event) {Final floatx = Event.getx ();Final floaty = event.gety ();Final intViewFlags = Mviewflags;Final intAction = Event.getaction ();//view is not an enable, it consumes the touch event, just returns and does not enter into the PerformClick () method        if((ViewFlags & enabled_mask) = = DISABLED) {if(Action = = motionevent.action_up && (mprivateflags & pflag_pressed)! =0) {setpressed (false); }//A disabled view that's 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); }if(Mtouchdelegate! =NULL) {if(Mtouchdelegate.ontouchevent (event)) {return true; }        }if((viewflags & clickable) = = Clickable | |                (ViewFlags & long_clickable) = = long_clickable) | | (ViewFlags & context_clickable) = = context_clickable) {Switch(action) { CaseMOTIONEVENT.ACTION_UP:Booleanprepressed = (Mprivateflags & pflag_prepressed)! =0;if((Mprivateflags & pflag_pressed)! =0|| prepressed) {//Take focus if we don't have an it already and we should in                        //Touch mode.                        BooleanFocustaken =false;if(Isfocusable () && isfocusableintouchmode () &&!isfocused ())                        {Focustaken = Requestfocus (); }//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; }when//switch is finished, it will eventually return true            return true; }//If Click,longclick and contextclickable are false, returns false        return false; }

As can be seen, a normal veiw (i.e. enable), and can be clicked, when Action_up, will eventually enter the PerformClick () this method to go

Can look again, the implementation of the Performanceclick method

 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; }

The OnClick method in Onclicklistener is eventually executed, which is the method that we usually implement.

At the same time, you can also see that you can clickable,longclickable and contextclickable as long as there is a true, then at the end of the switch will also return true, This returns to the Dispatchtouchevent method above, returning result to true, which is the complete consumption (processing) of the touch event .

Here can take a look at the complete source code, the overall structure is once inside the IF statement, switch execution is complete, return true, that is, to ensure that the touch event is fully processed.

Of course, if clickable,longclickable and contextclickable are all three false, they will not go into the IF statement, and return to the False,dispatchtouchevent method directly is false, That is, the touch event is not handled, this is the beginning, we only set ontouchlistener for myview without setting the Onclicklistener when the view class default is not clickable, then when we click on the MyView, Action_down executes, the OnTouch () method returns False, and then Ontouchevent returns false, so that subsequent events do not continue, so there is no action_up.

Well, this finally cleared up the touch event distribution mechanism for view (excluding ViewGroup).

Finally, the following conclusions are drawn:

The order in which each method executes when the view receives a touch event

Ontouch–>ontouchevent–>onclick

Ontouch default returns False, returns True when subsequent events cannot be executed

Dispatchtouchevent returns true to handle the touch event, and the return result is affected by the Ontouchevent method

Ontouchevent returns true to indicate that a touch event has been consumed, otherwise it is not consumed.

The true and false of the view enable property does not fully determine the pass of the touch event, but it also has to consider its listener

Doubts: Here the source code in context_clickable This attribute is not able to understand, online also found no explanation.

Android View event Distribution mechanism grooming

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.