流式布局,好处就是父类布局可以自动的判断子孩子是不是需要换行,什么时候需要换行,可以做到网页版的标签的效果。今天就是简单的做了自定义的流式布局。
具体效果:
原理:
其实很简单,Measure  Layout。只需要这两个步骤就可以搞定了。完全的手动去Measure  Layout。
我们看一下代码。
解释就在代码里面做注释了,因为使用为知笔记写的博客,格式不符合代码格式。大家可以看具体的源码。最后又源码下载地址。
1.Measure  测量 
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int lineHeight = 0 ;
int lineWidth = 0 ; 
int width = 0 ; 
int height = 0 ; 
int childCount = getChildCount();
Log.i("Test", getPaddingLeft() + "==right="  +getPaddingRight());
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams params = (MarginLayoutParams)                                       childView.getLayoutParams();
int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ; 
int childHeight  = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin ; 
if ((lineWidth + childWidth ) > widthSize - getPaddingLeft() - getPaddingRight() ) {
width = Math.max(width, lineWidth);
lineWidth = childWidth ; 
height += lineHeight ; 
lineHeight = childHeight; 
}else {
lineWidth += childWidth ; 
lineHeight = Math.max(lineHeight, childHeight);
}
if (i  == childCount-1) {
width = Math.max(width, lineWidth);
height += lineHeight ; 
}
}
height += getPaddingTop() + getPaddingBottom() ;
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY?widthSize:width, 
heightMode == MeasureSpec.EXACTLY?heightSize:height);
}
2.onLayout  布局
@Override
protected void onLayout(boolean a, int l, int t, int r, int b) {
childViewList.clear(); 
int childCount = getChildCount() ; 
int width = getWidth();
int lineWidth = 0 ;
int lineHeight = 0 ; 
List<View> lineViews = new ArrayList<View>();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ; 
int childHeight = childView.getMeasuredHeight() + params.topMargin +  params.bottomMargin  ;
if (lineWidth + childWidth > width - getPaddingLeft() - getPaddingRight()) {
childViewList.add(lineViews);
lineViews = new ArrayList<View>();
if (i == 0 ) {
lineHeight += getPaddingTop() ; 
}else if (i== childCount - 1) {
lineHeight += getPaddingBottom() ; 
}
this.lineHeight.add(lineHeight);
lineHeight = 0 ; 
lineWidth = 0 ; 
}
lineWidth += childWidth; 
lineHeight = Math.max(lineHeight, childHeight) ;
lineViews.add(childView);
}
childViewList.add(lineViews);
this.lineHeight.add(lineHeight);
int left = getPaddingLeft() ;
int top = getPaddingTop(); 
for (int i = 0; i < childViewList.size(); i++) {
lineViews = childViewList.get(i);
for (int j = 0; j < lineViews.size(); j++) {
View childView = lineViews.get(j);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int lc = left + params.leftMargin ; 
int tc = top + params.topMargin ; 
int rc = lc + childView.getMeasuredWidth()  ; 
int bc = tc + childView.getMeasuredHeight() ; 
childView.layout(lc,tc,rc,bc);
left += params.leftMargin + childView.getMeasuredWidth() + params.rightMargin ; 
}
left =  getPaddingLeft() ;
top += this.lineHeight.get(i) ; 
}
}
代码下载地址:
百度网盘:  http://pan.baidu.com/s/1hqH1kFU
        <p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>