什么是流式布局?其实我们在平时遇到过,只是有可能叫不出它的名字。

如图:

如上图,就是一个流式布局的样式。

&esmp;这里,将记录一下怎么实现这个功能。其实实现这个功能的方法,就是自定义ViewGroup。

自定义ViewGroup的时候,要注意两点:

1.子View和父View大小的测量。

2.子View的在父View里面怎么摆放。

想要解决上面的两个问题,就得重写两个方法,分别是:onMeasure方法,在这个方法我们通常来测量子View和父View的大小;onLayout方法,在这个方法里面,我们通常来决定子View在父View的摆放。

1.重写onMeasure方法

//测量父控件和子控件的大小

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

int widthMode = MeasureSpec.getMode(widthMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

int heightMode = MeasureSpec.getMode(heightMeasureSpec);

int width = getMeasuredWidth();

int height = 0;

int lineWidth = 0;

int lineHeight = 0;

int childWidth = 0;

int childHeight = 0;

for (int i = 0, n = getChildCount(); i < n; i++) {

View child = getChildAt(i);

measureChild(child, widthMeasureSpec, heightMeasureSpec);

MarginLayoutParams marginLayoutParams = (MarginLayoutParams) child.getLayoutParams();

Log.i("main", "width = " + child.getMeasuredWidth() + " height = " + child.getMeasuredHeight() + " leftMargin = " + marginLayoutParams.leftMargin + " rightMargin = " + marginLayoutParams.rightMargin);

childWidth = child.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;

childHeight = child.getMeasuredHeight() + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;

//换行

if (lineWidth + childWidth > width) {

lineWidth = childWidth;

height += lineHeight;

} else {

lineWidth += childWidth;

lineHeight = Math.max(childHeight, lineHeight);

}

if (i == n - 1) {

height += lineHeight;

}

}

setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width, heightMode == MeasureSpec.EXACTLY ? heightSize : height);

}

2.重写onLayou方法

private List> mAllViews = new ArrayList>();

private List mLineHeights = new ArrayList();

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

mAllViews.clear();

mLineHeights.clear();

int width = getWidth(); // 父布局的宽度

List lineViews = new ArrayList();

int childWidth = 0;

int childHeight = 0;

int lineWidth = 0;

int lineHeight = 0;

Log.i("main", "childCount = " + getChildCount() + " width = " + width);

for (int i = 0, n = getChildCount(); i < n; i++) {

View child = getChildAt(i);

MarginLayoutParams marginLayoutParams = (MarginLayoutParams) child.getLayoutParams();

childWidth = child.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;

childHeight = child.getMeasuredHeight() + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;

if (childWidth + lineWidth > width) {

mAllViews.add(lineViews);

mLineHeights.add(lineHeight);

lineViews = new ArrayList();

lineWidth = 0;

lineHeight = childHeight;

}

lineWidth += childWidth;

lineHeight = Math.max(lineHeight, childHeight);

lineViews.add(child);

}

mAllViews.add(lineViews);

mLineHeights.add(lineHeight);

int top = 0;

int left = 0;

Log.i("main", "n = " + mAllViews.size() + " m = " + lineViews.size());

for(int i = 0, n = mAllViews.size(); i < n; i++)

{

lineViews = mAllViews.get(i);

for(int j = 0, m = lineViews.size(); j < m; j++)

{

View child = lineViews.get(j);

if(child.getVisibility() == View.GONE)

{

continue;

}

MarginLayoutParams marginLayoutParams = (MarginLayoutParams) child.getLayoutParams();

int lc = left + marginLayoutParams.leftMargin;

int tc = top + marginLayoutParams.topMargin;

int rc = lc + child.getMeasuredWidth();

int bc = tc + child.getMeasuredHeight();

Log.i("main", "lc = " + lc + " tc = " + tc + " rc = " + rc + " bc = " + bc);

child.layout(lc, tc, rc, bc);

left += child.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;

}

left = 0;

top += mLineHeights.get(i);

}

}

在自定义ViewGroup的时候,一定要定义ViewGroup的LayoutParams。所以还要重写generateLayoutParams方法。

@Override

public LayoutParams generateLayoutParams(AttributeSet attrs) {

return new MarginLayoutParams(getContext(), attrs);

}

android自定义流式布局思路,Android 自定义控件基础-流式布局相关推荐

  1. java数字时钟代码,Android自定义数字时钟代码,android自定义时钟,package jp.t

    Android自定义数字时钟代码,android自定义时钟,package jp.tpackage jp.tsmsogn.digitalclock;import java.util.Calendar; ...

  2. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  3. Android自定义壁纸预览界面,Android仿主流壁纸App设置界面

    摘要:项目中做到在线壁纸应用,在壁纸设置界面也是参考了主流壁纸应用的做法,例如小米,vivo,搜狗等都是采用了类似下图的界面布局.这里将介绍如何做出类似布局和功能. 在图中,当手指滑动滑块的时候,背景 ...

  4. android自定义camera预览区域,android camera摄像surfaceview预览界面特定区域(该区域可移动)...

    1.自定义一个imageview用来设定surfaceview上的特定区域. public class DrawImageView extends ImageView { private Paint ...

  5. android 自定义加载动画效果,Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. ...

  6. android自定义水平长方形进度条,Android 自定义水平进度条的圆角进度

    有时项目中需要实现水平圆角进度,如下两种,其实很简单 下面开始看代码,先从主界面布局开始看起: xmlns:tools="http://schemas.android.com/tools&q ...

  7. android 自定义绘画,【整理】Android 自定义视图之画图

    Android 自定义视图之画图 首先简单的一个画矩形的例子 public class DrawView extends View { public DrawView(Context context) ...

  8. android 自定义 build.gradle,Gradle for Android 第二篇( Build.gradle入门 )

    这一系列暂不更新,相关技术讨论,请移步微信群,谢谢,希望大家多多支持! 新年新气象,奋斗的一年,在这一章,我们将学习以下内容: 理解Gradle文件 编写简单的构建任务 自制构建脚本 如果你还没有看g ...

  9. Android自定义睡眠下表统计图,Android 进阶自定义View(5)图表统计PieChartView圆饼图的实现...

    今天讲图表统计中比较常用的一个,像支付宝的月账单啥的,都是用圆饼图来做数据统计的,先看一下我最终实现的效果图: image.png 该效果实际上是两个实心圆叠加后的效果. image.png imag ...

  10. Android自定义壁纸预览界面,Android自定义动态壁纸开发(时钟)

    看到有些手机酷炫的动态壁纸,有没有好奇过他们是如何实现的,其实我们自己也可以实现. 先看效果 上图是动态壁纸钟的一个时钟. 我们先来看看 Livewallpaper(即动态墙纸)的实现,Android ...

最新文章

  1. Excel 2007 (Excel.Application) Workbooks.Add 出现内存不够的解决办法
  2. elastichd安装部署
  3. 架构师成长系列 | 云原生时代的 DevOps 之道
  4. oracle索引对模糊查询,Oracle索引
  5. (第二篇)Vue计算属性、侦听器、过滤器
  6. 搭建微信令牌中控服务器,使用ThinkJs搭建微信中控服务的实现方法
  7. 使用iBatis数据映射框架吧
  8. 五大软件设计原则学习笔记1——单一职责原则
  9. 使用rpm安装mysql_如何使用rpm安装MySQL
  10. Android开发,你应该知道的
  11. python动态变量名以及调用_Python 动态变量名与调用介绍
  12. scala语言课程设计
  13. 台达触摸屏和vfd-m变频器通讯控制监视程序 使用modbus rtu通讯方式,在触摸屏可以直接控制变频器
  14. utorrent设置上传速度_设置好uTorrent让你的下载速度飞起来
  15. 计算机作文英语初中,初中英语常见的作文类型及应对技巧
  16. PS快速美白磨皮方法
  17. Ice飞冰初始化《二》
  18. MQTT学习之初识mqtt
  19. peewee mysql_Peewee、MySQL和INSERT忽略
  20. Altium Designer——常见贴片钽电容封装尺寸及特性

热门文章

  1. 火车头使用PHP插件过滤emoji四字节字符
  2. Spring源码——声明式事务流程
  3. 2. IPV6报头格式
  4. 如何正确看待当下很美很火的RPA
  5. mysql set字段_MySQL的SET字段类型
  6. 织梦整站源码蓝色简洁大气电脑操作系统软件下载网站模板 带手机版
  7. 从零到有,从入门到入土
  8. ubuntu输入法安装[zz]
  9. appserv 部署php,在Windows下应用AppServ快速配置PHP开发环境
  10. 苹果6s升级后显示无服务器,苹果手机更新完就无服务了怎么处理