package com.cheikh.lazywaimai.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.cheikh.lazywaimai.R;
import java.util.ArrayList;
import java.util.List;
/**
* 自动换行的一个布局容器,可以设置每个childView的水平间距和垂直间距
* author:cheikh.wang on 16/8/10 11:49
* email:wanghonghi@126.com
*/
public class FixWrapLayout extends ViewGroup {
private List<List<View>> mAllViews = new ArrayList<>();
private List<Integer> mLineHeight = new ArrayList<>();
private int mHorizontalSpacing;
private int mVerticalSpacing;
public FixWrapLayout(Context context) {
this(context, null);
}
public FixWrapLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FixWrapLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (attrs != null) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.FixWrapLayout);
mHorizontalSpacing = (int) array.getDimension(R.styleable.FixWrapLayout_horizontal_spacing, 0);
mVerticalSpacing = (int) array.getDimension(R.styleable.FixWrapLayout_vertical_spacing, 0);
array.recycle();
}
}
/**
* 设置水平间隔
* @param horizontalSpacing
*/
public void setHorizontalSpacing(int horizontalSpacing) {
mHorizontalSpacing = horizontalSpacing;
invalidate();
}
/**
* 获取水平间隔
* @return
*/
public int getVerticalSpacing() {
return mVerticalSpacing;
}
/**
* 设置垂直间隔
* @param verticalSpacing
*/
public void setVerticalSpacing(int verticalSpacing) {
mVerticalSpacing = verticalSpacing;
invalidate();
}
/**
* 获取垂直间隔
* @return
*/
public int getHorizontalSpacing() {
return mHorizontalSpacing;
}
/**
* 获取view的宽度,包含margin
* @param v
* @return
*/
private int getChildWidth(View v) {
LayoutParams params = v.getLayoutParams();
if (params instanceof MarginLayoutParams) {
MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams();
return lp.leftMargin + lp.rightMargin + v.getMeasuredWidth();
} else {
return v.getMeasuredWidth();
}
}
/**
* 获取view的高度,包含margin
* @param v
* @return
*/
private int getChildHeight(View v) {
LayoutParams params = v.getLayoutParams();
if (params instanceof MarginLayoutParams) {
MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams();
return lp.topMargin + lp.bottomMargin + v.getMeasuredHeight();
} else {
return v.getMeasuredHeight();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
if (childCount == 0) {
setMeasuredDimension(0, 0);
return;
}
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
int lineWidth = 0;
int lineHeight = 0;
mAllViews.clear();
mLineHeight.clear();
List<View> lineViews = new ArrayList<>();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int childWidth = getChildWidth(child);
int childHeight = getChildHeight(child);
int horizontalSpacing = lineWidth != 0 ? mHorizontalSpacing : 0;
int verticalSpacing = lineHeight != 0 ? mVerticalSpacing : 0;
if ((lineWidth + horizontalSpacing + childWidth) <= widthSize) {
lineViews.add(child);
lineWidth += horizontalSpacing + childWidth;
lineHeight = Math.max(childHeight, lineHeight);
} else {
mLineHeight.add(lineHeight);
mAllViews.add(lineViews);
lineViews = new ArrayList<>();
lineViews.add(child);
width = Math.max(widthSize, lineWidth);
height += lineHeight + verticalSpacing;
lineWidth = childWidth;
lineHeight = childHeight;
}
if (i + 1 == childCount) {
width = Math.max(width, lineWidth);
height += lineHeight;
mLineHeight.add(lineHeight);
mAllViews.add(lineViews);
}
}
width = widthMode == MeasureSpec.EXACTLY ? widthSize : width;
height = heightMode == MeasureSpec.EXACTLY ? heightSize : height;
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = 0;
int top = 0;
int rowMaxHeight;
List<View> rowViews;
for (int row = 0; row < mAllViews.size(); row++) {
rowViews = mAllViews.get(row);
rowMaxHeight = mLineHeight.get(row);
for (int col = 0; col < rowViews.size(); col++) {
View child = rowViews.get(col);
if (child.getVisibility() == View.GONE) {
continue;
}
left += left != 0 ? mHorizontalSpacing : 0;
int lc = left;
int tc = top;
LayoutParams params = child.getLayoutParams();
if (params instanceof MarginLayoutParams) {
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
//计算childView的left,top,right,bottom
lc = left + lp.leftMargin;
tc = top + lp.topMargin;
}
int rc = lc + child.getMeasuredWidth();
int bc = tc + child.getMeasuredHeight();
child.layout(lc, tc, rc, bc);
left += getChildWidth(child);
}
left = 0;
top += rowMaxHeight + mVerticalSpacing;
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}