Typically, Android implements a custom control in three different ways.
Ⅰ, inherits existing controls, and expands the functionality of its controls.
Ⅱ, combining existing controls to implement more powerful controls.
Ⅲ, overriding view for a new control
As mentioned above, how to inherit existing controls from a custom control, let's discuss the second issue. How to combine controls to implement a powerful custom control.
Let's take a look at the benefits of creating a composite control, which creates a collection of controls that have the combined functionality. So what do we generally do, we usually inherit a suitable viewgroup, and then create a new function for him, thus forming a new function of the control. We also specify some new properties for this control, which makes him very extensible. Okay, so much nonsense, let's take the example of a control--the title bar--for almost every app, to introduce the practice of combining controls.
First, let me answer why I want to reuse the title bar:
Ⅰ, so that the application has a unified style.
Ⅱ, reuse the title bar, but also we will change the title bar in the future is very convenient, really achieve "write once, run everywhere" effect, and do not have a lot of trouble, each page is modified.
Ⅲ, exposing the calling interface to callers, gives more flexibility in controlling the title bar, making it more powerful.
So, the title bar grows that way, see:
Let's start with a simple analysis. This is a custom control that, like Android's native controls, makes it easy for callers to set the properties of the control. Therefore, it is very necessary to set some properties for this control, it is very simple to provide some custom properties for a view, just create a Attrs.xml property file under the values directory in the RES resource directory, and define the properties you need in the file. This custom control custom property is as follows:
<declare-styleablename= "TitleBar"> <attrname= "title"format= "string" /> <attrname= "Titletextsize"format= "Dimension" /> <attrname= "Titletextcolor"format= "Color" /> <attrname= "Titlelefttext"format= "string" /> <attrname= "Titleleftbackground"format= "Color|reference" /> <attrname= "Titlelefttextcolor"format= "Color" /> <attrname= "Titlerighttext"format= "string" /> <attrname= "Titlerightbackground"format= "Color|reference" /> <attrname= "Titlerighttextcolor"format= "Color" /> </declare-styleable>
We use the <declare-styleable> tag to declare the custom attribute to use, and use the Name property to determine the name of the reference. Use format to determine the format of the reference data. In this custom control custom property corresponding list is as follows:
Ⅰ, title--text corresponding to the title
Ⅱ, titletextsize--text size corresponding to title
Ⅲ, titletextcolor--text color of the corresponding title
Ⅳ, titlelefttext--text corresponding to the left button
Ⅴ, titleleftbackground--corresponds to the background of the left button
Ⅵ, titlelefttextcolor--corresponds to the text color of the left button
Ⅶ, titlerighttext--text corresponding to the right button
Ⅴ, titlerightbackground--corresponds to the background of the right button
Ⅵ, titlerighttextcolor--corresponds to the text color of the right button
Here, it should be pointed out that the background of the left and right buttons, that can be a color type, can also correspond to the corresponding picture, so we can use the "|" To separate the different properties.
Well, since, with the definition of a custom attribute, we need to customize a titlebar control to get these well-defined property values, and above, we mentioned that general composite controls are generally inherited with viewgroup controls, here, for our convenience, On inheritance and relativelayout. How to get the property value, the system provides typedarray such data structure can be very convenient to get the property set, the code to get the property is as follows:
Private voidinitattrs (AttributeSet attrs) {TypedArray ta= This. GetContext (). Obtainstyledattributes (Attrs, R.styleable.titlebar); if(Ta! =NULL) {title=ta.getstring (R.styleable.titlebar_title); Titletextsize=ta.getdimension (R.styleable.titlebar_titletextsize,16); Titletextcolor=ta. GetColor (R.styleable.titlebar_titletextcolor,0); Titlelefttext=ta.getstring (R.styleable.titlebar_titlelefttext); Titleleftbackground=ta. getdrawable (R.styleable.titlebar_titleleftbackground); Titlelefttextcolor=Ta.getcolor (R.styleable.titlebar_titlelefttextcolor,0); Titlerighttext=ta.getstring (R.styleable.titlebar_titlerighttext); Titlerightbackground=ta. getdrawable (R.styleable.titlebar_titlerightbackground); Titlerighttextcolor=Ta.getcolor (R.styleable.titlebar_titlerighttextcolor,0); Ta.recycle (); } }
Here, it is worth mentioning that you need to call Typedarray's Recycle method to recycle the resource.
Now that we have the properties for this combo control, what we're going to do is combine the buttons and text boxes of this combo control together, and the code of the combination looks like this:
Private voidInitview () {LeftButton=NewButton (GetContext ()); Titletextview=NewTextView (GetContext ()); Rightbutton=NewButton (GetContext ()); Leftbutton.settextcolor (Titlelefttextcolor); Leftbutton.setbackgrounddrawable (Titleleftbackground); Leftbutton.settext (Titlelefttext); Rightbutton.settextcolor (Titlerighttextcolor); Rightbutton.setbackgrounddrawable (Titlerightbackground); Rightbutton.settext (Titlerighttext); Titletextview.settext (title); Titletextview.settextsize (titletextsize); Titletextview.settextcolor (Titletextcolor); Mleftlayoutparams=Newlayoutparams (layoutparams.wrap_content, layoutparams.match_parent); Mleftlayoutparams.addrule (Relativelayout.align_parent_left); AddView (LeftButton, mleftlayoutparams); Mcenterlayoutparams=Newlayoutparams (layoutparams.wrap_content, layoutparams.match_parent); Mcenterlayoutparams.addrule (relativelayout.center_in_parent); AddView (Titletextview, mcenterlayoutparams); Mrightlayoutparams=Newlayoutparams (layoutparams.wrap_content, layoutparams.match_parent); Mrightlayoutparams.addrule (Relativelayout.align_parent_right); AddView (Rightbutton, mrightlayoutparams); }
We see that some of the properties defined above have been copied to these combined controls to make the composite control "flesh and Blood".
Since this is a custom control, is a UI template, should each caller click the left and right buttons, the implementation may not be the same, we should do is to expose the interface, so that the caller has the flexibility to control the two buttons. Then the definition of the interface is as follows:
Public Interface Clicklistener { void Click (int tag); } Private Clicklistener Listener;
In the template method, for the left and right buttons to increase the Click event, call the interface click Method, the code is as follows:
Private voidSetlistener () {Leftbutton.setonclicklistener ( This); Rightbutton.setonclicklistener ( This); } @Override Public voidOnClick (View v) {if(Listener! =NULL) { if(v = =LeftButton) {Listener. Click (Left_button); } Else if(v = =Rightbutton) {Listener. Click (Right_button); } } }
In the code, we effectively determine whether the left button clicked, or the right button clicked.
With the definition of the interface in this template method, we call this callback code externally as follows:
Titlebar.setlistener (NewClicklistener () {@Override Public voidClick (inttag) { Switch(tag) { CaseTitleBar.LEFT_BUTTON:Toast.makeText (mainactivity. This, "left button is clicked", 0). Show (); Break; CaseTitleBar.RIGHT_BUTTON:Toast.makeText (mainactivity. This, "Right button is clicked", 0). Show (); Break; default: Break; } } });
This allows you to effectively control the click events of the left and right buttons on the outside.
To do so much, is to be able to effectively invoke this combo control, call the code of the composite control as follows:
<Relativelayoutxmlns:android= "Http://schemas.android.com/apk/res/android"Xmlns:custom= "Http://schemas.android.com/apk/res/com.example.test"Xmlns:tools= "Http://schemas.android.com/tools"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent"android:padding= "5DP"Tools:context=". Mainactivity "> <!--<include layout= "@layout/topbar"/> - <Com.example.test.TitleBarAndroid:id= "@+id/titlebar"Android:layout_width= "Match_parent"Android:layout_height= "40DP"Custom:titleleftbackground= "@drawable/blue_button"Custom:titlelefttext= "Back"Custom:titlelefttextcolor= "#FFFFFF"Custom:titlerightbackground= "@drawable/blue_button"Custom:titlerighttext= "More"Custom:titlerighttextcolor= "#FFFFFF"Custom:title= "Custom caption"Custom:titletextcolor= "#123412"custom:titletextsize= "10SP"/></Relativelayout>
Here, we need to tell you that the difference between a custom control and a native control call is:
Ⅰ, the reference custom control must reference its full class name.
When Ⅱ, referencing custom control custom properties, you must reference a custom namespace, which is referenced by the following method:
Xmlns:custom= "Http://schemas.android.com/apk/res/com.example.test"
The final effect of this control is:
This is my Package title bar, welcome everyone to spit Groove.
Android Custom View Kick One--combine existing controls