流式布局之FlowLayout使用
2017-06-27 11:46
387 查看
package com.a520it.mygoogleplay.ui;
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
{
private List mLines = new ArrayList(); // 用来记录描述有多少行View
private Line mCurrrenLine; // 用来记录当前已经添加到了哪一行
private int mHorizontalSpace = 10;
private int mVerticalSpace = 10;
}
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
{
private List mLines = new ArrayList(); // 用来记录描述有多少行View
private Line mCurrrenLine; // 用来记录当前已经添加到了哪一行
private int mHorizontalSpace = 10;
private int mVerticalSpace = 10;
public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public FlowLayout(Context context) { super(context); // TODO Auto-generated constructor stub } public void setSpace(int horizontalSpace, int verticalSpace) { this.mHorizontalSpace = horizontalSpace; this.mVerticalSpace = verticalSpace; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 清空 mLines.clear(); mCurrrenLine = null; int layoutWidth = MeasureSpec.getSize(widthMeasureSpec); // 获取行最大的宽度 int maxLineWidth = layoutWidth - getPaddingLeft() - getPaddingRight(); // 测量孩子 int count = getChildCount(); for (int i = 0; i < count; i++) { View view = getChildAt(i); // 如果孩子不可见 if (view.getVisibility() == View.GONE) { continue; } // 测量孩子 measureChild(view, widthMeasureSpec, heightMeasureSpec); // 往lines添加孩子 if (mCurrrenLine == null) { // 说明还没有开始添加孩子 mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace); // 添加到 Lines中 mLines.add(mCurrrenLine); // 行中一个孩子都没有 mCurrrenLine.addView(view); } else { // 行不为空,行中有孩子了 boolean canAdd = mCurrrenLine.canAdd(view); if (canAdd) { // 可以添加 mCurrrenLine.addView(view); } else { // 不可以添加,装不下去 // 换行 // 新建行 mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace); // 添加到lines中 mLines.add(mCurrrenLine); // 将view添加到line mCurrrenLine.addView(view); } } } // 设置自己的宽度和高度 int measuredWidth = layoutWidth; // paddingTop + paddingBottom + 所有的行间距 + 所有的行的高度 float allHeight = 0; for (int i = 0; i < mLines.size(); i++) { float mHeigth = mLines.get(i).mHeigth; // 加行高 allHeight += mHeigth; // 加间距 if (i != 0) { allHeight += mVerticalSpace; } } int measuredHeight = (int) (allHeight + getPaddingTop() + getPaddingBottom() + 0.5f); setMeasuredDimension(measuredWidth, measuredHeight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // 给Child 布局---> 给Line布局 int paddingLeft = getPaddingLeft(); int offsetTop = getPaddingTop(); for (int i = 0; i < mLines.size(); i++) { Line line = mLines.get(i); // 给行布局 line.layout(paddingLeft, offsetTop); offsetTop += line.mHeigth + mVerticalSpace; } } class Line { // 属性 private List<View> mViews = new ArrayList<View>(); // 用来记录每一行有几个View private float mMaxWidth; // 行最大的宽度 private float mUsedWidth; // 已经使用了多少宽度 private float mHeigth; // 行的高度 private float mMarginLeft; private float mMarginRight; private float mMarginTop; private float mMarginBottom; private float mHorizontalSpace; // View和view之间的水平间距 // 构造 public Line(int maxWidth, int horizontalSpace) { this.mMaxWidth = maxWidth; this.mHorizontalSpace = horizontalSpace; } // 方法 /** * 添加view,记录属性的变化 * * @param view */ public void addView(View view) { // 加载View的方法 int size = mViews.size(); int viewWidth = view.getMeasuredWidth(); int viewHeight = view.getMeasuredHeight(); // 计算宽和高 if (size == 0) { // 说还没有添加View if (viewWidth > mMaxWidth) { mUsedWidth = mMaxWidth; } else { mUsedWidth = viewWidth; } mHeigth = viewHeight; } else { // 多个view的情况 mUsedWidth += viewWidth + mHorizontalSpace; mHeigth = mHeigth < viewHeight ? viewHeight : mHeigth; } // 将View记录到集合中 mViews.add(view); } /** * 用来判断是否可以将View添加到line中 * * @param view * @return */ public boolean canAdd(View view) { // 判断是否能添加View int size = mViews.size(); if (size == 0) { return true; } int viewWidth = view.getMeasuredWidth(); // 预计使用的宽度 float planWidth = mUsedWidth + mHorizontalSpace + viewWidth; if (planWidth > mMaxWidth) { // 加不进去 return false; } return true; } /** * 给孩子布局 * * @param offsetLeft * @param offsetTop */ public void layout(int offsetLeft, int offsetTop) { // 给孩子布局 int currentLeft = offsetLeft; int size = mViews.size(); // 判断已经使用的宽度是否小于最大的宽度 float extra = 0; float widthAvg = 0; if (mMaxWidth > mUsedWidth) { extra = mMaxWidth - mUsedWidth; widthAvg = extra / size; } for (int i = 0; i < size; i++) { View view = mViews.get(i); int viewWidth = view.getMeasuredWidth(); int viewHeight = view.getMeasuredHeight(); // 判断是否有富余 if (widthAvg != 0) { // 改变宽度 int newWidth = (int) (viewWidth + widthAvg + 0.5f); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec); viewWidth = view.getMeasuredWidth(); viewHeight = view.getMeasuredHeight(); } // 布局 int left = currentLeft; int top = (int) (offsetTop + (mHeigth - viewHeight) / 2 + 0.5f); // int top = offsetTop; int right = left + viewWidth; int bottom = top + viewHeight; view.layout(left, top, right, bottom); currentLeft += viewWidth + mHorizontalSpace; } } }
}
相关文章推荐
- 流式布局FlowLayout使用
- 使用Adapter设计模式打造一个流式布局FlowLayout
- 我可能使用假的流式布局。自定义XFlowLayout
- 使用TabLayout实现单行的flowlayout(标签流式布局)
- 【安卓小笔记】使用FlowLayout实现流式布局
- Android-->FlowRadioGroup(流式布局RadioGroup, 自定义View的简单使用)
- Java图形化界面设计——布局管理器之FlowLayout(流式布局)
- 100行Android代码自定义一个流式布局-FlowLayout
- 自定义ViewGroup实现流式布局FlowLayout
- 转:Java图形化界面设计——布局管理器之FlowLayout(流式布局)其他请参考转载出处网址
- iOS流布局UICollectionView使用FlowLayout进行更灵活布局
- iOS开发——高级篇——流水布局UICollectionViewFlowLayout的基本使用
- 跟我学JAVA(5)图形化界面设计——布局管理器之FlowLayout(流式布局)
- 二十九、Java图形化界面设计——布局管理器之FlowLayout(流式布局)
- 自定义流式布局控件FlowLayout
- 自定义ViewGroup,流式布局FlowLayout
- android 实现流式布局FlowLayout
- 100行Android代码自定义一个流式布局-FlowLayout
- Java图形化界面设计——布局管理器之FlowLayout(流式布局)
- 三、Java图形化界面设计——布局管理器之FlowLayout(流式布局)