一个需求,直接上gif图:
(1)点击 添加选项按钮,会增加一个item
(2)然后切换类型的时候,需要清除所有的item,添加另一种类型的item
下面来完成这个自定义控件,让它继承自ViewGroup
public class CustomAddViewLayout extends ViewGroup
构造函数的,可以简单地写一写:
public CustomAddViewLayout(Context context) {
this(context,null);
}
public CustomAddViewLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CustomAddViewLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
可以根据自己的需求来。
主要是onMeasure和onLayout方法,先看一下onMeasure方法
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//建议的长宽,但还不是最终的,由模式决定
int suggestWidth = MeasureSpec.getSize(widthMeasureSpec);
int suggestHeight = MeasureSpec.getSize(heightMeasureSpec);
int count = getChildCount();
int childHeight = 0;
int totalHeight = 0;
int resultHeight = suggestHeight;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
childHeight = child.getMeasuredHeight();
if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED){
totalHeight += getChildAt(i).getMeasuredHeight();
}
}
if(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED){
if(totalHeight>suggestHeight){
resultHeight = suggestHeight;
}else {
resultHeight = totalHeight;
}
}
setMeasuredDimension(suggestWidth,resultHeight);
由于在xml中使用这个控件的时候,在点击之前是没有item的,所以它的高度并不固定,使用wrap_content属性,在onMeasure方法中模式有可能是MeasureSpec.AT_MOST或者MeasureSpec.UNSPECIFIED的,这里这要对这两种进行判断,宽度我这里是match_parent,所以不用再计算。
接下来看onLayout方法:
int totalHeight = 0;//子view在y轴上的bottom
int currentTop = getPaddingTop();//子view在y轴上的top
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childHeight = child.getMeasuredHeight();
totalHeight += childHeight;
child.layout(getPaddingLeft(),currentTop,child.getMeasuredWidth(),totalHeight);
currentTop += childHeight;
}
代码不多,理解起来也不困难。
还有一些其他的方法就是:
提供给外界,增加item的
public void addItemView(View view){
addView(view);
requestLayout();
invalidate();
}
删除所有的item:
public void deleteItemView(int index){
removeViewAt(index);
requestLayout();
invalidate();
}
当然了,具体的需求还是看自己。
如果有兴趣,可以去我的github上看看:https://github.com/ckwcc/CustomAddItemView