自定义控件-宫格图片
效果:
这种布局,用RecyclerView的grid布局也可以搞定,但是阔以锻炼一波对自定义Viewgroup的子控件的测量和摆放。
1.自定义属性提取
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="GridImageViewGroup">
//上一行子控件与下一行子控件的间隔
<attr name="childVerticalSpace" format="dimension"/>
//左边子控件和右边子控件的间隔
<attr name="childHorizontalSpace" format="dimension"/>
//每一行图片的个数
<attr name="columnNum" format="integer"/>
</declare-styleable>
</resources>
2.自定义类
public class GridImageViewGroup extends ViewGroup {
private int columnNum = 3; //列数
private int childVerticalSpace = 0; //垂直的间距
private int childHorizontalSpace = 0; //水平间距
private int childWidth = 0;
private int childHeight = 0;
public GridImageViewGroup(Context context) {
this(context, null);
}
public GridImageViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GridImageViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.GridImageViewGroup);
if (attributes != null) {
childVerticalSpace = attributes.getDimensionPixelSize(
R.styleable.GridImageViewGroup_childVerticalSpace, 0);
childHorizontalSpace = attributes.getDimensionPixelSize(
R.styleable.GridImageViewGroup_childHorizontalSpace, 0);
columnNum = attributes.getInt(
R.styleable.GridImageViewGroup_columnNum, 3);
attributes.recycle();
}
}
//点击监听
public interface ClickItemImg {
void clickItemImg();
}
private ClickItemImg clickItemImg;
public void setClickListener(ClickItemImg clickItemImg) {
this.clickItemImg = clickItemImg;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
//除去间隔,控件宽度为屏幕的几分之一
switch (widthMode) {
case MeasureSpec.EXACTLY:
childWidth = (widthSize - getPaddingLeft() -
getPaddingRight() - (columnNum - 1) * childHorizontalSpace) / columnNum;
childHeight = childWidth;
break;
default:
childWidth = 150;
childHeight = childWidth;
break;
}
int childCount = getChildCount();
if (childCount > 0) {
int width = widthSize;
//行数
int rowCount = childCount / columnNum +
(childCount % columnNum != 0 ? 1 : 0);
//容器实际高度
int vh = rowCount * childHeight +
(rowCount > 0 ? rowCount - 1 : 0) * childVerticalSpace;
setMeasuredDimension(width, vh);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = 0;
int top = 0;
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
left = (i % columnNum) * (childWidth + childHorizontalSpace);
top = (i / columnNum) * (childHeight + childVerticalSpace);
child.layout(left, top, left + childWidth, top + childHeight);
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
addInitView();
}
private void addInitView() {
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.mipmap.img);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
addView(imageView);
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (clickItemImg != null) {
clickItemImg.clickItemImg();
}
}
});
}
}