自定义ViewGroup,一般分为四步走
1,继承自ViewGroup
public class CustomLayout extends ViewGroup {
public CustomLayout(Context context, AttributeSet attr) {
this(context, attr, 0);
}
public CustomLayout(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
}
}
2,自定义的ViewGroup的属性-在value文件下的attrs.xml声明如下代码
<declare-styleable name="CustomLayout">
<attr name="custom" format="integer" />
</declare-styleable>
然后在CustomLayout初始化的时候,获取自定义属性的值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomLayout);
final int len = typedArray.getIndexCount();
for (int i = 0; i < len; i++) {
int styledAttr = typedArray.getIndex(i);
switch (styledAttr) {
case R.styleable.CustomLayout_custom:
custom = typedArray.getInteger(i, 0);
break;
default:
break;
}
}
怎么使用这个自定义属性就不在此赘述了,相信大家都懂。。。
3,覆盖onMeasure方法,测量值+测量模式来确定ViewGroup的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int len = getChildCount();
final int width = MeasureSpec.getSize(widthMeasureSpec);
int height = getPaddingTop();
.....
for (int i = 0; i < len; ++i) {
View child = getChildAt(i);
final ViewGroup.LayoutParams lp = child.getLayoutParams();
int mode;
if (lp.width > 0) {
mode = MeasureSpec.EXACTLY;
} else {
if (lp.width == LayoutParams.MATCH_PARENT) {
mode = MeasureSpec.EXACTLY;
} else {
mode = MeasureSpec.AT_MOST;
}
}
final int childWidthSpec = MeasureSpec.makeMeasureSpec(numWidth, mode);
final int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
.....
setMeasuredDimension(width, height + getPaddingBottom());
}
onMeasure的主要作用
-
确定子view的宽和高,
-
确定自己的宽和高。
-
根据子View 的布局文件,为子view设置测量模式和测量值
测量 = 测量模式+测量值
测量模式由三种:EXCTLY:指定大小
AT_MOST:指定最大的大小
UNSPCIFIED:不指定大小,要多大就是多大。一般用于ScroolView中
4,覆盖onLayout方法,指定每个子view的布局规则
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int len = getChildCount();
final int width = r - l;
.....
int maxRowHeight = 0;
for (int i = 0; i < len; ++i) {
View child = getChildAt(i);
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
.....
child.layout(left, top, left + childWidth, top + childHeight);
.....
}
}
这样就是自定义viewGroup的流程,具体的逻辑需要根据自身的业务逻辑来确定,因此这里的代码作为参考
网友评论