文章目录
ShifterLayout:子控件的宽度不固定
/**
* 可以换行的布局控件,其中的子控件宽度不固定
*/
public class ShifterLayout extends ViewGroup {
public ShifterLayout(Context context) {
super(context);
}
public ShifterLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childTop = this.getPaddingTop();
int childLeft = this.getPaddingLeft();
int childWidth = 0;
int childHeight = 0;
int tempChildLeft = 0;
for(int i=0; i<getChildCount(); i++) {
View child = getChildAt(i);
if(child.getVisibility() == VISIBLE) {
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
//换行
tempChildLeft = childLeft +lp.leftMargin + childWidth;
if(tempChildLeft >= getMeasuredWidth()) {
childLeft = this.getPaddingLeft();
childTop += childHeight + lp.bottomMargin+lp.topMargin;
}
//
child.layout(childLeft , childTop,
childLeft+childWidth, childTop+ childHeight);
childLeft += childWidth+lp.rightMargin+lp.leftMargin;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childTop = this.getPaddingTop();
int childLeft = this.getPaddingLeft();
int childWidth = 0;
int childHeight = 0;
int height = 0;
int tempChildLeft = 0;
int width = MeasureSpec.getSize(widthMeasureSpec);
for(int i=0; i<getChildCount(); i++) {
View child = this.getChildAt(i);
if(child.getVisibility() == VISIBLE) {
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
//换行
tempChildLeft = childLeft +lp.leftMargin + childWidth;
if(tempChildLeft >= width) {
childLeft = this.getPaddingLeft();
childTop += childHeight + lp.bottomMargin+lp.topMargin;
}
childLeft += childWidth+lp.rightMargin+lp.leftMargin;
}
}
height = childTop + childHeight + this.getPaddingBottom();
setMeasuredDimension(width, height);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}
ShifterLayout2:子控件的宽度一致且固定
/**
* 可以换行的布局控件,其中的子控件宽度相同且固定
*/
public class ShifterLayout2 extends ViewGroup {
private int childWidth, childHeight;
public ShifterLayout2(Context context) {
super(context);
}
public ShifterLayout2(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// super.onLayout(changed, l, t, r, b);
int childTop = this.getPaddingTop();
int childLeft = this.getPaddingLeft();
int tempChildLeft = 0;
for(int i=0; i<getChildCount(); i++) {
View child = getChildAt(i);
if(child.getVisibility() == VISIBLE) {
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
//换行
tempChildLeft = childLeft +lp.leftMargin + childWidth;
if(tempChildLeft >= getMeasuredWidth()) {
childLeft = this.getPaddingLeft();
childTop += childHeight + lp.bottomMargin+lp.topMargin;
}
//
child.layout(childLeft , childTop,
childLeft+childWidth, childTop+ childHeight);
childLeft += childWidth+lp.rightMargin+lp.leftMargin;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
View childView = getChildAt(0);
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
//其他类想要获取布局控件中的子控件的宽高:布局控件.getChildAt(0).getMeasuredWidth/Height()
//不measure其他子控件,目前没有遇到问题
measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
// for(int i=0; i<getChildCount(); i++) {
// View child = getChildAt(i);
// measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
// }
MarginLayoutParams lp =
(MarginLayoutParams) childView.getLayoutParams();
int childLeftMargin = lp.leftMargin;
int childTopMargin = lp.topMargin;
int childBottomMargin = lp.bottomMargin;
childWidth = childView.getMeasuredWidth();
childHeight = childView.getMeasuredHeight();
int childWidth2 = childWidth + childLeftMargin;
int childHeight2 = childHeight + childTopMargin + childBottomMargin;;
int columnNum = (measureWidth)/(childWidth2);
int height = 0;
int childCount = getChildCount();
if(childCount<columnNum) {
height = childHeight2;
}
else {
height += (childCount/columnNum)*childHeight2;
if(childCount%columnNum != 0) {
height += childHeight2;
}
}
height -= childBottomMargin;
setMeasuredDimension(measureWidth, height);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}