Let's look at how the clickable and onclick are defined in view:
Case com.android.internal.r.styleable.view_clickable: if false ) {|= clickable; | = clickable; } break;
The above code is the definition of the clickable attribute in view source, and the default value is False.
CaseR.styleable.view_onclick:if(context.isrestricted ()) {Throw NewIllegalStateException ("The Android:onclick attribute cannot" + "be used within a restricte D context "); } FinalString HandlerName =a.getstring (attr); if(HandlerName! =NULL) {Setonclicklistener (NewOnclicklistener () {PrivateMethod Mhandler; Public voidOnClick (View v) {if(Mhandler = =NULL) { Try{Mhandler=GetContext (). GetClass (). GetMethod (HandlerName, View.class); } Catch(nosuchmethodexception e) {intID =getId (); String Idtext= id = = no_id? "": "with ID" +GetContext (). Getresources (). Getresourceentryname (ID)+ "'"; Throw NewIllegalStateException ("Could not find a method" +HandlerName+ "(View) in the activity" + getcontext (). GetClass () + ' for OnClick Handl ER "+" on view + view. This. GetClass () +Idtext, E); } } Try{Mhandler.invoke (GetContext (), View. This); } Catch(illegalaccessexception e) {Throw NewIllegalStateException ("Could not execute non" + "public method of the activity ", E); } Catch(InvocationTargetException e) {Throw NewIllegalStateException ("Could not Execute" + "method of the activity", E); } } }); } Break;
Above is the definition of the onclick attribute in the view source code. You can see that it calls the Setonclicklistener () method to register the click event, below the source code of the Setonclicklistener () method:
/** * Register a callback to be invoked WH En this view is clicked. If This view was not * clickable, it becomes clickable. * @param The callback that would run * * @see #setClickable (Boolean) Span style= "color: #008000;" >*/ public void Setonclicklistener (Onclicklistener l) { if (!isclickable ()) {setclickable ( true ); } getlistenerinfo (). Monclicklistener = L; }
If the clickable property is False then it becomes true after this method is called.
When you inherit the button from the view, the ImageView control uses the OnClick property in the XML, you can see through the print log that clickable is changed from the default to true, but the same textview that inherits from view is still false. Why does this happen?
Then learn about the process of loading an XML file from Android.
Take the view as an example to illustrate. When we use the Setoncontentview () method to load the layout file. The view element in the layout file invokes the following constructor to create a new View object
/*** Constructor That's called when inflating a view from XML. This was called * when a view was being constructed from the XML file, supplying attributes * that were specified in The XML file. This version uses a default style of * 0, so the attribute values applied is those in the Context ' s Theme * and the given AttributeSet. * * <p> * The method Onfinishinflate () is called after all children has been * added. * * @paramContext The context the view is running in, through which it can * access the current theme, resources, ET C. *@paramattrs The attributes of the XML tag is inflating the view. * @see#View (Context, attributeset, int)*/ PublicView (Context context, AttributeSet attrs) { This(context, Attrs, 0); }
View Code
This (context, attrs, 0) will also invoke the public View (context context, AttributeSet attrs, int defstyleattr) {} constructor. you can see that the Setonclicklistener () method called when the OnClick property is defined is called when the object is created.
Let's take a look at the TextView control, which he has done with clickable in the constructor.
Booleanfocusable = mmovement! =NULL|| Getkeylistener ()! =NULL; Booleanclickable =focusable; BooleanLongclickable =focusable; N=A.getindexcount (); for(inti = 0; I < n; i++) { intattr =A.getindex (i); Switch(attr) { Casecom.android.internal.r.styleable.view_focusable:focusable=A.getboolean (attr, focusable); Break; Casecom.android.internal.r.styleable.view_clickable:clickable=A.getboolean (attr, clickable); Break; Casecom.android.internal.r.styleable.view_longclickable:longclickable=A.getboolean (attr, longclickable); Break; } }
You can see from the code that the default value of clickable becomes the value of focuseable, and TextView calls the constructor of the parent class by default when the constructor is called to create a new object, that is, by Setonclicklistener () The processed clickable value is true, but it is given a new value in the TextView constructor. This can also explain why the value of clickable is still false after the TextView control has used the OnClick property in the XML file, and the clickable value becomes true after calling the Setonclicklistener () method in code. That is because the Setonclicklistener () method that is called in the code is after the TextView object is established.
TextView the clickable value is still false when the onclick attribute is added to the XML file.