int childWidth = child.getMeasuredWidth() + lp.leftMargin
- lp.rightMargin;
// 得到子View占据的高度
int childHeight = child.getMeasuredHeight() + lp.topMargin
- lp.bottomMar

gin;
if (lineWidth + childWidth > sizeWidth) {// 需要进行换行
width = Math.max(width, lineWidth); // 得到最大宽度
lineWidth = childWidth; // 重置lineWidth
height += lineHeight; // 得到高度
lineHeight = childHeight;// 重置LineHeight
} else {// 不需要进行换行
lineWidth += childWidth;// 叠加行宽
lineHeight = Math.max(lineHeight, childHeight);
}
if (i == childCount - 1) {// 处理最后一个子View的情况
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
// wrapcontent
-
setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth
-
width, modeHeight == MeasureSpec.EXACTLY ? sizeHeight
-
height);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
mAllChildViews.clear();
mLineHeight.clear();
int width = getWidth();// 获取当前ViewGroup宽度
int lineWidth = 0;
int lineHeight = 0;
List lineViews = new ArrayList();// 记录当前行的View
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child
.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
// 需要换行
if (lineWidth + childWidth + lp.leftMargin + lp.rightMargin > width) {
mLineHeight.add(lineHeight); // 记录lineHeight
mAllChildViews.add(lineViews); // 记录当前行的Views
// 重置 行的宽高
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
// 重置当前行的View集合;
lineViews = new ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin
- lp.bottomMargin);
lineViews.add(child);
}
// 处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
// 设置子View的位置
int left = 0;
int top = 0;
// 获取行数
int lineCount = mAllChildViews.size();
for (int i = 0; i < lineCount; i++) {
// 当前行的views和高度
lineViews = mAllChildViews.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 cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
// 进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin
- lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
/**
- 与当前ViewGroup对应的LayoutParams
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}
二.xml部分
xml布局中加上这个
<com.jky.mobilebzt.view.XCFlowLayout
android:id="@+id/xcf_hot_words"
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_marginLeft="@dimen/margin_lsmall"
android:layout_marginBottom="@dimen/margin_normal"
android:layout_marginRight="@dimen/margin_normal" />
三.初始化数据部分
@SuppressLint(“NewApi”)
private void initHotWordViews() {
MarginLayoutParams lp = new MarginLayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
"
android:layout_marginRight="@dimen/margin_normal" />
三.初始化数据部分
@SuppressLint(“NewApi”)
private void initHotWordViews() {
MarginLayoutParams lp = new MarginLayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
本文详细介绍了自定义FlowLayout布局的实现原理及代码实现过程。通过测量子View尺寸、计算换行逻辑来适应不同屏幕尺寸,实现了类似标签云的效果。适用于Android应用中需要灵活布局的场景。
1560

被折叠的 条评论
为什么被折叠?



