所谓流式布局指的是ViewGroup中同一行的宽度不足以容纳下一个子view时,进行换行处理,而不需要考虑子view的大小,每一行的高度以其中最高者为准。Talk is cheap, Show you the code。
首先,应当集成ViewGroup,为了确定View的宽高,就必须重onMeasure(intwidthMeasureSpec, intheightMeasureSpec),为了确定子view的位置,必须重写onLayout(booleanchanged, intl, intt, intr, intb)。
关键代码如下:
/**
* 如果加入当前child,则超出最大宽度,则的到目前最大宽度给width,类加height 然后开启新行
*/
if(lineWidth + childWidth > sizeWidth - getPaddingLeft() - getPaddingRight()) {
width = Math.max(lineWidth,childWidth);// 取最大的
lineWidth = childWidth;// 重新开启新行,开始记录
// 叠加当前高度,
height += lineHeight;
// 开启记录下一行的高度
lineHeight = childHeight;
mLocationMap.put(child, newLocation(left,top + height,childWidth + left -childHorizontalSpace,height + child.getMeasuredHeight() + top));
}else{// 否则累加值lineWidth,lineHeight取最大高度
mLocationMap.put(child, newLocation(lineWidth + left,top + height,lineWidth + childWidth -childHorizontalSpace+ left,height + child.getMeasuredHeight() + top));
lineWidth += childWidth;
lineHeight = Math.max(lineHeight,childHeight);
}
这段代码用来最终确定ViewGroup的宽高。其中mLocationMap已经计算出了子view的位置,因此onLayout方法很简单,
protected voidonLayout(booleanchanged, intl, intt, intr, intb) {
intcount = getChildCount();
for(inti =0;i < count;i++) {
View child = getChildAt(i);
if(child.getVisibility() ==GONE)
continue;
Location location =mLocationMap.get(child);
child.layout(location.left,location.top,location.right,location.bottom);
}
}
效果如下:
源码地址github上https://github.com/SharksLee/FlowLayout,觉得对你有帮助的话,顺手给个星吧,另外动动你可爱的小手,给个赞赏吧!!