public class FlowLayout extends ViewGroup {
private int mHorizonalSpace=8;
private int mVerticalSpace=8;
/** 当前的流式布局不确定有几行,可能有多行也可能没有行.**/
private List<Line> mLines=new ArrayList<Line>();
private int mContainerWidth;
private int mContainerHeight;
/***
行对象
*/
private class Line
{
private int lineWidth=0;
private int lineHeight=0;
/**存放行的元素 **/
private List<View> views=new ArrayList<View>();
public int getLineWidth() {
return lineWidth;
}
public int getLineHeight() {
return lineHeight;
}
public List<View> getViews() {
return views;
}
// 还需要支持往行里面添加元素
public void addChild(View view) {
// 如果当前行不存在这个元素的话就把元素添加进来
if (!views.contains(view)) {
// 测量
view.measure(0, 0);
if (views.size() ==0) {
// 当前只有一个元素的,宽与高就由它决定
lineWidth += view.getMeasuredWidth() + mHorizonalSpace;
lineHeight = view.getHeight();
} else {
// 有不同高度的元素
lineWidth += view.getMeasuredWidth() + mHorizonalSpace;
lineHeight = Math.max(lineHeight, view.getMeasuredHeight());
}
views.add(view);
}
}
}
public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
/**.xml 画页面, 所见即所得 */
public FlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
/**.java new FlowLayout(context) 动态输出*/
public FlowLayout(Context context) {
super(context);
init(context);
}
/*** 方法
@param context
*/
private void init(Context context) {
//setBackgroundColor(Color.BLUE);
}
/*** 方法 一。测量
@param widthMeasureSpec
@param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mLines.clear();
// 一。容器它是占满屏幕
mContainerWidth = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
// 二。高度是由行数决定, 所以针对所有控件进行测量宽高,分行就可以算出行数了.
int childCount = getChildCount();
Line currLine = null;
for (int i = 0; i < childCount; i++) {
// 获取每个元素
View child = getChildAt(i);
// 测宽高
child.measure(0, 0);
int cHeight = child.getMeasuredHeight();
int cWidth = child.getMeasuredWidth();
//为第一个元素创建行
if (mLines.size() == 0) {
// 新建一行
currLine = new Line();
mLines.add(currLine);
}
//如果未满一行往里添加
int remainWidth = mContainerWidth - currLine.getLineWidth();
if (remainWidth >=cWidth) {
currLine.addChild(child);
} else {//存放空间不够再新建一行
currLine = new Line();
mLines.add(currLine);
currLine.addChild(child);
}
}
//累加高度
mContainerHeight = 0;
for (int i = 0; i < mLines.size(); i++) {
if (i != (mLines.size() - 1)) {
mContainerHeight += mLines.get(i).getLineHeight() + mVerticalSpace;
} else {
mContainerHeight += mLines.get(i).getLineHeight();
}
}
// 使用包裹内容的方式式把每一个元素计算出容器的宽与高,设置给当前容器
setMeasuredDimension(mContainerWidth, mContainerHeight);
}
/*** 方法 二。摆放 left top bottom right
@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 lineLeft=0;
int lineTop=0;
for(int i=0;i<mLines.size();i++)
{
Line line = mLines.get(i);
int eachViewSpace=(mContainerWidth-line.getLineWidth())/line.getViews().size();
//容器空间
if(i>0)
{
//第二行开始top要累加
lineTop+=mLines.get(i-1).getLineHeight()+mVerticalSpace;
}
//对每一行中的元素进行摆放
List<View> views = line.getViews();
lineLeft=0;
for(int index=0;index<views.size();index++)
{
//把里面的每一个
View lineChild = views.get(index);
if (index > 0) {
// 本行中的第二个元素
lineLeft = views.get(index - 1).getRight() + mHorizonalSpace;
}
int cWidth = lineChild.getMeasuredWidth();
int cHeight = lineChild.getMeasuredHeight();
int mode=MeasureSpec.EXACTLY;//80+10 andoid_layoutWidth="90dp"
//创建measure使用数值的方式 MODE+SIZE
int measureWidth=MeasureSpec.makeMeasureSpec(cWidth+eachViewSpace, mode);
lineChild.measure(measureWidth, 0);//0代表使用包裹获取宽高
//摆放
int cLeft=lineLeft;
int cTop=lineTop;
int cRight=cLeft+cWidth+eachViewSpace;
int cBottom=cTop+cHeight;
lineChild.layout(cLeft, cTop, cRight, cBottom);
}
}
}
/*** 方法 三。画图,一般不去重写
@param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
流式布局FlowLayout
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 1.介绍 流式布局的应用还是很广泛的,比如搜索热词、关键词标签等,GitHub上已经有很多这样的布局了,但是还是想...
- 一、静态布局(Static Layout)即传统Web设计,网页上的所有元素的尺寸一律使用px作为单位。1、布局特...
- 本文所使用的FlowLayout来自于鸿洋大神的框架。正好现在在做项目需要用到。自己试着用了下,具体可以看效果图鸿...