<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在android开发中,通常会有热门搜索的功能,这种功能的显示一般有两种,一个是有规则的排列,此种方式用GridView加载数据即可;但对于非规则性的排列,android系统并没有提供这种的View,这种布局称这流布局,这篇文章将会实现一个流布局的自定义控件。最终效果图如下:</span>
这篇文章就讲一下怎么实现这种布局,这其中有参考过慕课网的课程,如果有不好的地方,还请大神们指出,谢谢
一、onMeasure()
实现这个FlowLayout布局,主要在于计算每个子view所占的空间及如何排放,也就是要计算出布局中每一行排放几个子view,用一个for循环即可
for (int i = 0; i < mCount; i++) {
View child = getChildAt(i);
//measure width and height of the child view
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//get LayoutParams of child
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
//calculate the actual width and height of child view
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if (lineWidth + childWidth > viewWidth - getPaddingLeft() - getPaddingRight()) {
mAllViews.add(mLineViews);
mLineHeight.add(lineHeight);
//get max width
width = Math.max(width, lineWidth);
//add up lineHeight
height += lineHeight;
//reset
lineWidth = 0;
lineHeight = 0;
mLineViews = new ArrayList<View>();
}
mLineViews.add(child);
lineHeight = Math.max(lineHeight, childHeight);
lineWidth += childWidth;
}
这其中,在每次换到下一行时,将当前行的子view及当前行的height存放起来,这样可以在onLayout()方法中使用;
注意:还要对最后一行作处理,因为以上的for并没有把最后一行的view存放起来
//add the last row
mAllViews.add(mLineViews);
mLineHeight.add(lineHeight);
width = Math.max(lineWidth, width);
height += lineHeight;
这样,onMeasue()方法的核心代码完成
二、onLayout()
对布局及子view进行计算后,就要对这个view进行排放,也就是布局了,也用一个for循环完成
for (int i = 0; i < lineNumber; i++) {
lineViews = mAllViews.get(i);
lineHeight = mLineHeight.get(i);
for (int j = 0; j < lineViews.size(); j++) {
View child = lineViews.get(j);
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int lc = left + lp.leftMargin;
int tc = top + lp.topMargin;
int rc = lc + child.getMeasuredWidth();
int bc = tc + child.getMeasuredHeight();
child.layout(lc, tc, rc, bc);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = getPaddingLeft();
top += lineHeight;
}
好了,大功告成!如果有更好的方法,请大神们不吝赐教
顺便给个下载链接吧,FlowLayout源码