您的位置:首页 > 其它

最简单的自定义ViewGroup布局控件

2018-03-02 18:17 519 查看
本文为作者(石岩)原创,转载请指明出处:

http://blog.csdn.net/a1002450926/article/details/79426067

自定义ViewGroup布局控件,一般需要写onMeasure和onLayout这2个方法。下面代码可以说是入门自定义ViewGroup布局控件一个很好的案例,麻雀虽小,五脏俱全,如果大家把下面的代码完全理解,我相信以后大家遇到自己动手写自定义布局控件时会更加的得心应手。

代码演示

/**
*  石岩
*/
public class CustomViewGroup extends ViewGroup {
private static final int OFFSET = 80;

public CustomViewGroup(Context context) {
this(context, null);
}

public CustomViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CustomViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
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);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
// 处理CustomViewGroup的paddingTop
if (i == 0) {
top = getPaddingTop();
}
// 处理子控件marginTop marginBottom
top += lp.topMargin + lp.bottomMargin;
// 处理CustomViewGroup的paddingLeft 处理子控件marginLeft marginRight
left = i * OFFSET + getPaddingLeft() + lp.leftMargin
+ lp.rightMargin;
right = left + child.getMeasuredWidth();
bottom = top + child.getMeasuredHeight();
child.layout(left, top, right, bottom);
top += child.getMeasuredHeight();
}

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;

// 计算子View的大小
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0,
lp.width);
int childHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0,
lp.height);
child.measure(childWidthSpec, childHeightSpec);

}
// 计算CustomViewGroup的宽度
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);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
// 处理子控件marginLeft marginRight
int widthAndOffset = i * OFFSET + child.getMeasuredWidth()
+ lp.leftMargin + lp.rightMargin;
width = Math.max(width, widthAndOffset);
}
// 处理CustomViewGroup的paddingLeft和paddingRight
width = width + getPaddingLeft() + getPaddingRight();
break;
}

// 计算CustomViewGroup的高度
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);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
// 处理子控件marginTop marginBottom
height += child.getMeasuredHeight() + lp.topMargin
+ lp.bottomMargin;
}
break;
}
// 处理CustomViewGroup的paddingTop和paddingBottom
height = height + getPaddingTop() + getPaddingBottom();

Log.e("width", width + "");
Log.e("height", height + "");
setMeasuredDimension(width, height);
}

// 获取MarginLayoutParams
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}


效果演示

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: