Android custom View
The most basic three methods of customizing a View are: onMeasure (), onLayout (), onDraw ();
A View is displayed in an activity through three steps: measurement, layout, and drawing.
They correspond to three actions: Measure, layout, and draw.
* Measure: onMeasure () determines the size of the View;
* Layout: onLayout() determines the position of the View in the ViewGroup;
* Draw: onDraw() decides to draw the View.
* Custom View: only need to rewrite onMeasure() and onDraw() * Custom ViewGroup: only need to rewrite onMeasure() and onLayout() A View, such as a TextView(no sub-views) * View group: PhoneWindow is the most basic window system in Android system, inherited from Windows class, responsible for managing interface display and event response. 2.DecorView is the starting node of the PhoneWindow View that inherits from the View class and is used as the entire View container to set window properties. 3.ViewRoot is created when the Activity starts and is responsible for managing, layout, rendering the window UI, and so on. *Top: the distance between the upper boundary of the child View and the upper boundary of the parent View; *Top: the distance between the upper boundary of the child View and the upper boundary of the parent View; *Left: the distance between the Left edge of the child view and the Left edge of the parent view; *Bottom: the distance between the lower boundary of the child view and the upper boundary of the parent view; *Right: the distance between the child View's Right edge and the parent View's left edge;Copy the code
Measure
1. Why should the system have measure process? Android recommends adaptive layout. The size of a control cannot be specified during UI drawing. Therefore, measure is required. 2. What does measeure do? Calculate the specific size of the adaptive control and map it to the screen. 3. For the adaptive size mechanism, how to measure a View tree reasonably? 4. How does a ViewGroup pass limits to its child views? Child Views are limited by Measurespec; MeasureSpec = mode + size ; The measurement specification encapsulates the limitations of the parent container on the layout of the View, and the content provides the width and height information (SpacMode and SpaceSize). SpaceSize refers to the reference size of SpaceMod, SpaceMode has the following three types: The parent control has no restrictions on its child View, which is typically used internally as a measurement state (such as ScrollView). *AT_MOST The size of the child View cannot be greater than the size specified by the parent control. 5.ScrollView nested ListViewCopy the code
Common methods in the onMeasure() method:
1. GetChildCount (): Get the number of child Views;
2. GetChildAt (I): get the ith child control;
3. SubView. GetLayoutParams (). The width/height set for child controls of the width or height;
4. MeasureChild (child, withMeasureSpec, heightMeasureSpec) : measurement of wide View high;
5. Child. GetMeasureHeight/width () : after measureChild () method can get in this way the son after the View of the wide high value;
6. GetPaddingLeft () : / Right/Top/Bottom padding around the access control;
7. SetMeasuredDimension (Width,height): Resets the width and height of the control.
Example: custom ViewGroup implementation of simple indentation;
// Indent size; private static final int OFFSET = 100; public MyViewGroup(Context context) { super(context); } public MyViewGroup(Context context, AttributeSet attrs) { super(context, attrs); } public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //1. Measure oneself; super.onMeasure(widthMeasureSpec, heightMeasureSpec); //2. Calculate the measurement limit information for each subview; int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); // Measure the size of the child View; // Measure the size of the child View. int childCount = getChildCount();for(int i = 0; i < childCount; i++){ View child = getChildAt(i); ViewGroup.LayoutParams lp = child.getLayoutParams(); int childWidthSpec = getChildMeasureSpec(widthMeasureSpec,0,lp.width); int childHeightSpec = getChildMeasureSpec(heightMeasureSpec,0,lp.height); child.measure(childWidthSpec,childHeightSpec); } int width = 0; int height = 0; //4. Obtain the size of View after measurement; //5.ViewGroup calculates its own size according to its own condition; switch (widthMode){case MeasureSpec.EXACTLY:
width = widthSize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
for(int i= 0; i < childCount; i++){ View child = getChildAt(i); int widthAddOffset = i * OFFSET+child.getMeasuredWidth(); width = Math.max(width,widthAddOffset); }break;
default:
break;
}
switch (heightMode){
case MeasureSpec.EXACTLY:
height = heightSize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
for(int i= 0; i < childCount; i++){ View child = getChildAt(i); height += child.getMeasuredHeight(); }break;
default:
break; } //6. Save its own size;setMeasuredDimension(width,height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //1. Traverse the child View / / 2. Determine your rules / / 3. Child View measurement size / / 4. Left, top, right, bottom, / / 6. Child, layout int left = 0; int top = 0; int right = 0; int bottom = 0; int childCount = getChildCount();for (int i = 0; i < childCount;i++){
View child = getChildAt(i);
left = i * OFFSET;
right = left +child.getMeasuredWidth();
bottom = top + child.getMeasuredHeight();
child.layout(left,top,right,bottom);
top += child.getMeasuredHeight();
}
}Copy the code
Realization effect as shown in figure;