自定义FlowLayout,android flowLayout实现,安卓framework开发书籍

本文详细介绍了自定义FlowLayout布局的实现原理及代码实现过程。通过测量子View尺寸、计算换行逻辑来适应不同屏幕尺寸,实现了类似标签云的效果。适用于Android应用中需要灵活布局的场景。

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);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值