首先看下效果图:
自定义组件FlowLayoutView代码
<pre name="code" class="java">import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/*
* @项目名: GoegleMarket
* @包名:
* @文件名: FlowLayoutView
* @创建者: Administrator
* @创建时间: 2016/8/1 0001 下午 12:08
* @描述: TODO
*/
public class FlowLayoutView extends ViewGroup {
private List<LineView> groupList = new ArrayList<>();
private LineView mCurrentLine;
private int verticalSpace = 15;
public FlowLayoutView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlowLayoutView(Context context) {
this(context,null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mCurrentLine = null;
groupList.clear();
//1.获取宽高信息
int width = MeasureSpec.getSize(widthMeasureSpec);
// int widthMode = MeasureSpec.getMode(widthMeasureSpec);
//父容器FlowLayoutvieW给孩子开辟的最大宽度
int maxWidth = width - getPaddingLeft() - getPaddingRight();
//2.根据宽高信息计算测量孩子
//获取孩子的数量,然后测量每个孩子的宽高
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
//获取每个孩子对象
View child = getChildAt(i);
//测量孩子
measureChild(child,widthMeasureSpec,heightMeasureSpec);
//由于所有的孩子分布在不同的行,所以在测量时进行判断,以便合理的添加孩子
if (mCurrentLine == null) {
//该行尚添加,进行添加
mCurrentLine = new LineView(maxWidth, 14);
mCurrentLine.addChild(child);
groupList.add(mCurrentLine);//添加行
} else {
if (mCurrentLine.canAddChild(child)) {
mCurrentLine.addChild(child);
} else {
//当前行添加孩子已达上限,新建下一行
mCurrentLine = new LineView(maxWidth,14);
mCurrentLine.addChild(child);
groupList.add(mCurrentLine);//添加行
}
}
}
//3.测量自己
Toast.makeText(getContext(),"" + groupList.size(),Toast.LENGTH_SHORT).show();
//根据已经添加的孩子,计算测量
int height = getPaddingTop();
for (LineView line : groupList) {
height += line.height;
height += verticalSpace;
}
setMeasuredDimension(width,height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = l;
int top = t + getPaddingTop();
for (LineView line : groupList) {
//布局孩子
line.layout(left,top);
//更新行参数
top += line.height;
top += verticalSpace;
}
}
class LineView{
public int maxWidh;
public int height;
public int Horizontolspace;
public List<View> childList = new ArrayList<>();
public int usedWidth;
public LineView(int maxWidh, int horizontolspace) {
this.maxWidh = maxWidh;
Horizontolspace = horizontolspace;
}
/**
* 是否可以继续添加孩子
* @param child
* @return
*/
public boolean canAddChild(View child){
if (childList.size() == 0) {
//没有孩子时,第一个孩子必然可以添加
return true;
}
//获取孩子的宽度
int childWidth = child.getMeasuredWidth();
if (usedWidth + Horizontolspace + childWidth > maxWidh) {
return false;
}
return true;
}
/**
* 添加孩子的方法
* @param child
*/
public void addChild(View child) {
//获取孩子的宽高
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
//添加孩子
childList.add(child);
//更新已使用的宽度信息
usedWidth += childWidth;
usedWidth += Horizontolspace;
//根据添加进来的孩子,动态获取行的高度
height = height > childHeight ? height : childHeight;
}
/**
* 在行内布局孩子的方法
* @param l left
* @param t top
*/
public void layout(int l,int t){
for (View child : childList) {
int left = l;
int top = t;
int right = left + child.getMeasuredWidth();
int bottom = top + child.getMeasuredHeight();
//布局孩子
child.layout(left,top,right,bottom);
//从每行的第二个孩子开始添加前更新l
l += child.getWidth();
l += Horizontolspace;
}
}
}
}
接着就可将其作为一个依赖的Lib库,引用到所需要的地方了
@Override
protected View getChildSuccessView() {
//rankfragment的具体化view页面
ScrollView scrollView = new ScrollView(UiUtil.getContext());
scrollView.setFillViewport(true);
//创建flowLayout对象
FlowLayoutView flowLayoutView = new FlowLayoutView(UiUtil.getContext());
flowLayoutView.setPadding(5,5,5,5);
//循环添加孩子的内容
for (String textContent : mData) {
TextView textView = new TextView(getContext());
textView.setTextSize(16);
textView.setPadding(5, 5, 5, 5);
textView.setGravity(Gravity.CENTER);
textView.setText(textContent);
//生成随机颜色背景
Random random = new Random();
int alpha = 255;
int r = 80 + random.nextInt(155);
int g = 80 + random.nextInt(155);
int b = 80 + random.nextInt(155);
//添加颜色背景需要gradientDrawable
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setCornerRadius(5);
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setColor(Color.argb(alpha, r, g, b));
//按压下的状态
GradientDrawable particalDrawable = new GradientDrawable();
particalDrawable.setCornerRadius(5);
particalDrawable.setShape(GradientDrawable.RECTANGLE);
particalDrawable.setColor(Color.GRAY);
//创建状态选择器
StateListDrawable selector = new StateListDrawable();
selector.addState(new int[]{android.R.attr.state_pressed}, particalDrawable);
selector.addState(new int[]{}, gradientDrawable);
//设置背景
textView.setBackground(selector);
//设置点击事件
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
//添加到flowLayout中
flowLayoutView.addView(textView,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
//将flowLayout添加到scrollView中
scrollView.addView(flowLayoutView);
return scrollView;
}