? ? ? ? 所謂流式布局指的是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,覺得對你有幫助的話,順手給個星吧,另外動動你可愛的小手,給個贊賞吧??!