How to customize a control is mainly divided into the following steps:
1. Declaration and acquisition of custom attributes
(1) Analysis of required custom attributes
(2) Define the declaration in res/values/attrs.xml, such as
<resources> <declare-styleable name= "Hookview" > <attr name= "Loadingtext" format= "string"/ > <attr name= "Completetext" format= "string"/> <attr name= "textSize" format= "Dimension"/> </declare-styleable></resources>
(3) Use in the layout XML file
Defines the name and then 3 properties, and then adds a custom control reference when the
xmlns:app= "Http://schemas.android.com/apk/res-auto"
Then use App:loadingtext = "string" To set the properties you want to configure
(4) In the view construction method to obtain
Get the properties you set by using Typedarray in your custom control
if (attrs! = null) { //Get custom attribute TypedArray ta = context.obtainstyledattributes (attrs, r.styleable.hookview); if (Ta.hasvalue (r.styleable.hookview_loadingtext)) Loadingtext = ta.getstring (r.styleable.hookview_ Loadingtext); if (Ta.hasvalue (r.styleable.hookview_completetext)) Completetext = ta.getstring (r.styleable.hookview_ Completetext); TextSize = Ta.getdimension (r.styleable.hookview_textsize); Ta.recycle (); }
This is used to remember recycle (), this is because the custom view, will be created with every activity create, therefore, the system needs to create a frequent array, memory and performance is a small overhead, if you do not use the pool mode, each time the GC to recycle, is likely to cause outofmemory, the program maintains a typedarray pool at runtime, when the program calls, it requests an instance to the pool, and then calls the Recycle () method to release the instance so that it can be reused by other modules. Remember to call recycle () after use.
2, measuring onmewsure (occupy much space)
The view is usually displayed on the screen to go through measure and then to layout. When calling the Onmeasure (int widthspec, int heightspec) method, the use of Measurespec is involved
Measurespec There are 3 modes of "UNSPECIFIED", "exactly", "At_most", respectively.
When we set width or height to fill_parent, the container calls the measure method of the child view when the layout is exactly, because the child view occupies the space of the remaining container, so its size is deterministic.
When set to Wrap_content, the container passes in the At_most, indicating the maximum size of the child view, so that the child view will set its own size according to this limit. When the size of a child view is set to an exact value, the container passes in exactly, and Measurespec's unspecified mode is usually the slide control to the child control The default behavior of the Onmeasure method for view is to set the minimum size of Mminwidth (typically 0) or drawable of the background when the mode is unspecified.
in the image, the Onmeasure method is called when the parent element is about to place the control. The parent control calls it to the child control asking a question, "How much place do you want to use?" ", and then pass in two parameters--widthmeasurespec and Heightmeasurespec. they indicate the space that the control can obtain and the metadata about the space description. the best way to return a result is to pass the height and width of the view to the Setmeasureddimension method.
Here's a look at the Classic View Onmeasure implementation
@Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int measuredheight = measure Height (HEIGHTMEASURESPEC); int measuredwidth = Measurewidth (Widthmeasurespec); Setmeasureddimension (Measuredheight, measuredwidth); } private int Measureheight (int measurespec) {int specmode = Measurespec.getmode (Measurespec); int specsize = measurespec.getsize (Measurespec); The Default size if no limits is specified. int result = 500; if (Specmode = = Measurespec.at_most) {//Calculate the ideal size of your//control within this maximum size. If your control fills the available//space return the outer bound. result = Specsize; } else if (Specmode = = measurespec.exactly) {//If your control can fit within these bounds return that value. result = Specsize; } return result; } private int Measurewidth (int measurespec) {int specmode = measurespec.getmode (measureSPEC); int specsize = measurespec.getsize (Measurespec); The Default size if no limits is specified. int result = 500; if (Specmode = = Measurespec.at_most) {//Calculate the ideal size of your control//within this maximum size. If your control fills the available space//return the outer bound. result = Specsize; } else if (Specmode = = measurespec.exactly) {//If your control can fit within these bounds return that value. result = Specsize; } return result; }
About Measurespec class here to say a little more,
It represents a 32-bit int value, the high 2 bits represent the Specmode (measurement mode), and the low 30 bits represent the specsize (the size of the specification in a measurement mode)
There are three commonly used functions about it:
static int getmode (int measurespec): Extract mode according to the measured value (format) provided (one of the three modes above)
static int getsize (int measurespec): Extracts the size value (this size is the size that we usually say) based on the measured value (format) provided.
static int makemeasurespec (int size,int mode): Creates a measure value (format) based on the provided size value and mode
3. Layout OnLayout (where to put)
4. Draw OnDraw (what to draw)
It is often necessary to master the API of canvas, Path , and possibly the interaction of property animations .
5, Ontouchevent
Need to do user interaction to capture event events
6, Onintercepttouchevent (ViewGroup)
Event interception in ViewGroup, where the event distribution mechanism needs to be mastered
The introduction is mainly these pieces of content, each piece needs to understand deeply, in see a custom View source code is often through these pieces down analysis
Getting Started with custom view