Custom ViewGroup knowledge summary – continuous update

1. The padding of the child is included in child.getMeasuredWidth()

The margin value of child needs to adapt itself.

2. In onMeasure method:

MeasuredWidth and measureHeight need to be measured on the child first.

ViewGroup#measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec)

ViewGroup#measureChildWithMargins(View child,int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)

MeasureChildWithMargins has a flaw. Its internal MarginLayoutParams are type-strong and do not add non-null and type-judging. If we were customing our ViewGroup, this would cause null Pointers and type-casting exceptions. In order to solve this problem, I from defines a method, detailed look at the following measureChildWithMarginsAndUsedSpace method.

3, when measuring the child, considering the defects of measureChildWithMargins here to implement a method: measureChildWithMarginsAndUsedSpace

protected void measureChildWithMarginsAndUsedSpace(View child, int parentWidthMeasureSpec, int widthUsed, Int parentHeightMeasureSpec, int heightUsed) {if (child.getLayOutParams () == null) {return; } final LayoutParams lp = child.getLayoutParams(); int paddingH = getPaddingLeft() + getPaddingRight() + widthUsed; int paddingV = getPaddingTop() + getPaddingBottom() + heightUsed; if (child.getLayoutParams() instanceof MarginLayoutParams) { final MarginLayoutParams mlp = (MarginLayoutParams) child.getLayoutParams(); paddingH += mlp.leftMargin + mlp.rightMargin; paddingV += mlp.topMargin + mlp.bottomMargin; } final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, paddingH, lp.width); final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, paddingV, lp.height); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); }Copy the code

4. When customizing a ViewGroup, you must consider the padding of the ViewGroup itself, as well as the padding and margin of the child.

If the Child is also a custom ViewGroup, there are considerations as well.

5. How to support child margin data conveniently? Override the ViewGroup#generateLayoutParams method

@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new MarginLayoutParams(getContext(), attrs);
}
Copy the code

Viewgroups only provide viewGroup.layoutParams, and MarginLayoutParams are implemented by the viewgroups themselves.

The best way for our ViewGroup to support MarginLayoutParams is to override the ViewGroup#generateLayoutParams method.

6. For some operations that need to limit the width, they can be performed in onMeasure.

Measure the actual width first, and if it exceeds expectations, make a second measurement based on its maximum length. Common custom layouts such as FlowLayout can be implemented in this way.

To be continued, stay tuned.