流式布局

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;


public class FlowLayout extends ViewGroup {
public FlowLayout(Context context) {
this(context, null);
}

public FlowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

private List<List<View>> mLineViews = new ArrayList<List<View>>();
private List<Integer> mLineHeight = new ArrayList<Integer>();

/**
* 测量所有子View大小,确定ViewGroup的宽高
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//由于onMeasure会执行多次,避免重复的计算控件个数和高度,这里需要进行清空操作
mLineViews.clear();
mLineHeight.clear();

//获取测量的模式和尺寸大小
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec) + getPaddingTop() + getPaddingBottom();


//记录ViewGroup真实的测量宽高
int viewGroupWidth = 0 - getPaddingLeft() - getPaddingRight();
int viewGroupHeight = getPaddingTop() + getPaddingBottom();

if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
viewGroupWidth = widthSize;
viewGroupHeight = heightSize;
} else {
//当前所占的宽高
int currentLineWidth = 0;
int currentLineHeight = 0;

//用来存储每一行上的子View
List<View> lineView = new ArrayList<View>();
int childViewsCount = getChildCount();
for (int i = 0; i < childViewsCount; i++) {
View childView = getChildAt(i);
//对子View进行测量
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childView.getLayoutParams();
int childViewWidth = childView.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;
int childViewHeight = childView.getMeasuredHeight() + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;

if (currentLineWidth + childViewWidth > widthSize) {
//当前行宽+View+左右外边距>ViewGroup的宽度,换行
viewGroupWidth = Math.max(currentLineWidth, widthSize);
viewGroupHeight += currentLineHeight;
//添加行高
mLineHeight.add(currentLineHeight);
//添加行对象
mLineViews.add(lineView);

//new新的一行
lineView = new ArrayList<View>();
//添加行对象里的子View
lineView.add(childView);
currentLineWidth = childViewWidth;

} else {
//当前行宽+View+左右外边距<=ViewGroup的宽度,不换行
currentLineWidth += childViewWidth;
currentLineHeight = Math.max(currentLineHeight, childViewHeight);
//添加行对象里的子View
lineView.add(childView);
}


if (i == childViewsCount - 1) {
//最后一个子View的时候
//添加行对象
mLineViews.add(lineView);
viewGroupWidth = Math.max(childViewWidth, viewGroupWidth);
viewGroupHeight += childViewHeight;
//添加行高
mLineHeight.add(currentLineHeight);

}


}

}
setMeasuredDimension(viewGroupWidth, viewGroupHeight);
}
/**
* 设置ViewGroup里子View的具体位置
*
* @param changed
* @param l
* @param t
* @param r
* @param b
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

int left = getPaddingLeft();
int top = getPaddingTop();
//一共有几行
int lines = mLineViews.size();
for (int i = 0; i < lines; i++) {
//每行行高
int lineHeight = mLineHeight.get(i);
//行内有几个子View
List<View> viewList = mLineViews.get(i);
int views = viewList.size();

for (int j = 0; j < views; j++) {
View view = viewList.get(j);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
int vl = left + marginLayoutParams.leftMargin;
int vt = top + marginLayoutParams.topMargin;
int vr = vl + view.getMeasuredWidth();
int vb = vt + view.getMeasuredHeight();
view.layout(vl, vt, vr, vb);
left += view.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;
}
left = getPaddingLeft();
top += lineHeight;
}
}

/**
* 指定ViewGroupLayoutParams
*
* @param attrs
* @return
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}

}




XML代码


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<EditText
android:id="@+id/main_edit"
android:layout_width="294dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:background="@drawable/shape_bg"
android:ems="10" />

<Button
android:id="@+id/main_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:background="@drawable/shape_bg"
android:text="搜索" />

<com.example.weekdome.FlowLayout
android:id="@+id/flow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="57dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="欧美影视"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="婚姻育儿"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="散文"
android:textColor="@color/colorAccent" />


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="程序员"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="大学生生活"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="运营互助帮"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="设计"
android:textColor="@color/colorAccent" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="5dp"
android:text="读书"
android:textColor="@color/colorAccent" />
</com.example.weekdome.FlowLayout>

<ListView
android:id="@+id/history_list"
android:layout_width="match_parent"
android:layout_height="356dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true" />

</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值