Android之自定义ViewGroup

时间:2022-08-30 08:04:02

今天看了鸿洋大神的自定义viewgroup,现在做一下笔记

首先,创建默认构造方法,如下所示
public FlowLayout(Context context) {
super(context,null);
}

public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs,0);
}

public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

先说一下自定义viewgroup的流程。
onMeasure(用于测量父类的宽高)–>onlayout(用于子类测量以及位置的摆放)

1.重写onMeasure方法:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取父类传递过来的参数, widthMeasureSpec用于获取父容器测量的宽度和测量模式
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

}

测量模式有以下三种:
MeasureSpec.EXACTLY:对应的是MATCH_PARENT,FILL_PARENT以及精确值,例如50dp之类
MeasureSpec.AT_MOST:对应的是WRAP_CONTENT
MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

接着,遍历所有子view
int cCount = getChildCount();
for (int i=0;i< cCount;i++){
View child = getChildAt(i);
measureChild(child,widthMeasureSpec,heightMeasureSpec);

//MarginLayoutParams从哪里来呢?我们一般会重写generateLayoutParams(AttributeSet attrs)方
//法,如下所示
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
}

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

generateLayoutParams确定了子类的layouparams,如果需要自定义,那么继承ViewGroup.LayoutParams,重写方法即可。

最后,调用setMeasuredDimension(width,height);
将测量到的宽高传入即可。

2.重写onLayout方法
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
int childCount = this.getChildCount();
for (int j=0;j< cCount;j++){
View child = getChildAt(j);
LayoutParams lParams = (LayoutParams) child.getLayoutParams();
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
lParams.top + childHeight);
}
}

获取对应的子view,然后对子view进行位置摆放。OVER!