android 实现流式布局FlowLayout
来源:互联网 发布:php true false 编辑:程序博客网 时间:2024/06/04 18:03
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
/**
* @author YeGuangRong
*
*/
public class FlowLayout extends ViewGroup{
public FlowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
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
}
/**
* 测量获取布局的宽和高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
/**
* 此部分可以获取Viewgroup为子View提供的测量模式和大小
*/
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int childCount = getChildCount();
int tatolHeight = 0;
int lineWidth = 0;
int maxWidth = 0;
//行数
int lineCount = 0;
//需要将测量子View的测量模式设置为AT_MOST(对应类似于wrap_content),否则如果使用父类的测量模式会被设为EXACTLY,这样就达不到流的效果
int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);//如果使用EXACTLY的话每个子控件都会布满一行,就达不到我们需要的效果
//遍历子控件,对每个子控件进行测量,最后得出ViewGroup最终的宽度和高度
for(int i = 0; i< childCount; i++){
View childView = getChildAt(i);
childView.measure(newWidthMeasureSpec, heightMeasureSpec);//开始测量子控件
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childView.getLayoutParams();//获取空见设置的margin值,前提是重写generateLayoutParams(AttributeSet attrs)这个方法,见下文
if((lineWidth + childView.getMeasuredWidth() + marginLayoutParams.leftMargin+marginLayoutParams.rightMargin)>widthSize){//当空间叠加后所需要的宽度大于ViewGroup所能提供的最大宽度,则需要换行
tatolHeight = tatolHeight + childView.getMeasuredHeight()+marginLayoutParams.bottomMargin+marginLayoutParams.topMargin;
if(maxWidth < lineWidth){//将宽度最大的那一行作为最终ViewGroup的宽度
maxWidth = lineWidth;
}
lineWidth = childView.getMeasuredWidth()+marginLayoutParams.leftMargin+marginLayoutParams.rightMargin;
}else{//不换行的情况,在行内将子控件叠加
lineWidth = lineWidth + childView.getMeasuredWidth()+marginLayoutParams.leftMargin+marginLayoutParams.rightMargin;
if(tatolHeight == 0){
tatolHeight= childView.getMeasuredHeight()+marginLayoutParams.bottomMargin+marginLayoutParams.topMargin;
}
}
}
/**
* 设置ViewGroup最终的宽和高
*/
if(maxWidth != 0){
setMeasuredDimension(maxWidth, tatolHeight);
}else{
setMeasuredDimension(lineWidth, tatolHeight);
}
}
/**
* 上面确定ViewGroup的宽和高后,我们需要对ViewGroup里面的子控件进行摆放,确定每个控件的位置(位置可通过l,t,r,b四个值来设定)。
* l,是控件的左边距离父控件(此处即为该ViewGroup)的距离,通过getLeft()可获得其值
* t,是控件的上边距离距离其父控件的距离,通过getTop()可获得其值.
* r,是控件的右边距离距离其父控件的距离,通过getRight()可获得其值.
* b,是控件的底边距离距离其父控件的距离,通过getBottom()可获得其值.
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
int childCount = getChildCount();
int left = 0,right = 0,top = 0,bottom = 0;
int measureWidth = getMeasuredWidth();
int measureHeight= getMeasuredHeight();
// Log.e("measureHeight", "measureHeight = "+measureHeight+" measureWidth = "+measureWidth);
for(int i = 0; i< childCount; i++){
View childView = getChildAt(i);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childView.getLayoutParams();
right = left + childView.getMeasuredWidth()+marginLayoutParams.rightMargin;
bottom = top + childView.getMeasuredHeight()+marginLayoutParams.bottomMargin;
if(i == 0){
left = marginLayoutParams.leftMargin;
}
if(right >= measureWidth){//如果摆放的子控件的右边大于ViewGroup的最大宽度 ,则将控件从下一行开始摆放
top = bottom+marginLayoutParams.topMargin;
left = marginLayoutParams.leftMargin;
right= left + childView.getMeasuredWidth()+marginLayoutParams.rightMargin;
bottom = top + childView.getMeasuredHeight()+marginLayoutParams.bottomMargin;
childView.layout(left, top, right, bottom);
left = right+marginLayoutParams.leftMargin;
}else{//不用换行时,从左到右摆放子控件
childView.layout(left, top, right, bottom);
left = right+marginLayoutParams.leftMargin;
}
}
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
}
1 0
- android 实现流式布局FlowLayout
- Android 流式布局FlowLayout
- Android流式布局-FlowLayout
- Android流式布局FlowLayout
- Android:FlowLayout流式布局
- Android FlowLayout 流式布局
- Android轻松实现流式布局之FlowLayout
- Android 实现FlowLayout流式布局(类似热门标签)
- Android 流式布局FlowLayout 实现关键字标签
- Android 实现FlowLayout流式布局(类似热门标签)
- Android 中实现FlowLayout 布局
- 自定义ViewGroup实现流式布局FlowLayout
- FlowLayout实现自定义的流式布局
- Android自定义流式布局-FlowLayout
- Android之FlowLayout流式布局
- Android自定义流式布局-FlowLayout
- Android开发流式布局FlowLayout
- Android自定义控件--流式布局(FlowLayout)
- Penguins DbTools数据库管理移植差分工具(EXCEL相关)
- 当你在浏览器地址栏输入一个URL后回车,将会发生的事情?
- tomcat上传war包部署时超大小限制解决
- mongodb聚合函数操作
- 安卓开发中的优秀工具
- android 实现流式布局FlowLayout
- 如何配置gradle环境
- 使用ffmpeg合并视频文件的三种方法
- Linux中crontab的坑爹环境变量问题
- JAVA-外观模式
- 知乎上某人的ios面试题
- 解决linux系统下oracle数据库方向键无效的问题
- the mobile samples for the ArcGIS API for Flex
- IOS 实现delegate链/广播