流式布局,好处就是父类布局可以自动的判断子孩子是不是需要换行,什么时候需要换行,可以做到网页版的标签的效果。今天就是简单的做了自定义的流式布局。
具体效果:
原理:
其实很简单,Measure Layout。只需要这两个步骤就可以搞定了。完全的手动去Measure Layout。
我们看一下代码。
解释就在代码里面做注释了,因为使用为知笔记写的博客,格式不符合代码格式。大家可以看具体的源码。最后又源码下载地址。
1.Measure 测量
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int lineHeight = 0 ;
int lineWidth = 0 ;
int width = 0 ;
int height = 0 ;
int childCount = getChildCount();
Log.i("Test", getPaddingLeft() + "==right=" +getPaddingRight());
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ;
int childHeight = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin ;
if ((lineWidth + childWidth ) > widthSize - getPaddingLeft() - getPaddingRight() ) {
width = Math.max(width, lineWidth);
lineWidth = childWidth ;
height += lineHeight ;
lineHeight = childHeight;
}else {
lineWidth += childWidth ;
lineHeight = Math.max(lineHeight, childHeight);
}
if (i == childCount-1) {
width = Math.max(width, lineWidth);
height += lineHeight ;
}
}
height += getPaddingTop() + getPaddingBottom() ;
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY?widthSize:width,
heightMode == MeasureSpec.EXACTLY?heightSize:height);
}
2.onLayout 布局
@Override
protected void onLayout(boolean a, int l, int t, int r, int b) {
childViewList.clear();
int childCount = getChildCount() ;
int width = getWidth();
int lineWidth = 0 ;
int lineHeight = 0 ;
List<View> lineViews = new ArrayList<View>();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ;
int childHeight = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin ;
if (lineWidth + childWidth > width - getPaddingLeft() - getPaddingRight()) {
childViewList.add(lineViews);
lineViews = new ArrayList<View>();
if (i == 0 ) {
lineHeight += getPaddingTop() ;
}else if (i== childCount - 1) {
lineHeight += getPaddingBottom() ;
}
this.lineHeight.add(lineHeight);
lineHeight = 0 ;
lineWidth = 0 ;
}
lineWidth += childWidth;
lineHeight = Math.max(lineHeight, childHeight) ;
lineViews.add(childView);
}
childViewList.add(lineViews);
this.lineHeight.add(lineHeight);
int left = getPaddingLeft() ;
int top = getPaddingTop();
for (int i = 0; i < childViewList.size(); i++) {
lineViews = childViewList.get(i);
for (int j = 0; j < lineViews.size(); j++) {
View childView = lineViews.get(j);
MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
int lc = left + params.leftMargin ;
int tc = top + params.topMargin ;
int rc = lc + childView.getMeasuredWidth() ;
int bc = tc + childView.getMeasuredHeight() ;
childView.layout(lc,tc,rc,bc);
left += params.leftMargin + childView.getMeasuredWidth() + params.rightMargin ;
}
left = getPaddingLeft() ;
top += this.lineHeight.get(i) ;
}
}
代码下载地址:
- 自定义ViewGroup 流式布局
使用 public class MainActivity extends Activity { @Override protected void onCreate(Bundle sav ...
- 28 自定义View流式布局
流式布局每行的行高以本行中最高的元素作为高,如果一个元素放不下到一行时直接到第二行 FlowLayoutView package com.qf.sxy.customview05.widget; imp ...
- Android控件进阶-自定义流式布局和热门标签控件
技术:Android+java 概述 在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧,类 ...
- 自定义View(三)--实现一个简单地流式布局
Android中的流式布局也就是常说的瀑布流很是常见,不仅在很多项目中都能见到,而且面试中也有很多面试官问道,那么什么是流式布局呢?简单来说就是如果当前行的剩余宽度不足以摆放下一个控件的时候,则自动将 ...
- Android 自动换行流式布局的RadioGroup
效果图 用法 使用FlowRadioGroup代替RadioGroup 代码 import android.content.Context; import android.util.Attribute ...
- Android 自定义View修炼-Android中常见的热门标签的流式布局的实现
一.概述:在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出哈) 类似的 ...
- 【Android - 自定义View】之自定义可滚动的流式布局
首先来介绍一下这个自定义View: (1)这个自定义View的名称叫做 FlowLayout ,继承自ViewGroup类: (2)在这个自定义View中,用户可以放入所有继承自View类的视图,这个 ...
- 自定义流式布局:ViewGroup的测量与布局
目录 1.View生命周期以及View层级 1.1.View生命周期 1.2.View层级 2.View测量与MeasureSpec类 2.1.MeasureSpec类 2.2.父View的限制 :测 ...
- Android流式布局实现
查看我的所有开源项目[开源实验室] 欢迎增加我的QQ群:[201055521],本博客client下载[请点击] 摘要 新项目用到了一种全新布局----Android标签流式布局的功能,正好一直说给大 ...
随机推荐
- JQ模拟触发事件
jQuery 事件 - trigger() 方法 jQuery 事件参考手册 实例 触发 input 元素的 select 事件: $("button").click(functi ...
- grafana使用小节
安装准备 安装grafana 安装mysql grafana操作步骤 新建数据源,支持mysql 数据库连接失败处理: https://www.jianshu.com/p/684bc3a77ac9 新 ...
- 从source安装python3.5和pip
按顺序来,先装上python3.5,source安装,命令是 ./configure --prefix="你想要的路径" make make install 然后是安装pip,但是 ...
- 如何在新导入的python项目中一次性生成依赖的第三方库
requirements.txt用来记录项目所有的依赖包和版本号,只需要一个简单的pip命令就能完成. pip freeze >requirements.txt 然后就可以用 pip insta ...
- PIE SDK栅格数据的创建
1. 功能简介 目前在地理信息领域中数据包括矢量和栅格两种数据组织形式.每一种数据有不同的数据格式,目前PIE SDK支持多种数据格式的数据创建,下面对栅格数据格式的数据创建功能进行介绍. 2. 功能 ...
- 转 AIX7.2+11.2.0.4RAC实施
参考 https://blog.csdn.net/alangmei/article/details/18310381 https://blog.csdn.net/smasegain/article/d ...
- DB Intro - MongoDB Basic
mongoDB basic from:http://www.tutorialspoint.com/mongodb prject:https://github.com/chenxing12/l4mong ...
- 【温故知新】c#抽象类abstract与接口interface
1.什么是抽象类 先来看MSDN对抽象类描述: 抽象类是一些留有部分或全部成员未实现的类,以便可以由派生类来提供实现. 在面向对象的编程中,抽象类用作层次结构的基类,并表示不同对象类型组的通用功能. ...
- 虚拟机xp系统中Oracle 10g的安装
1 安装过程(11步) 2.如果是xp系统可以直接并双击解压目录下的setup.ext,出现安装界面,如下: 3.输入口令和确认口令,如:oracle,点击下一步,出现如下进度条. 注:此口令即是管理 ...
- MySQL关联left join 条件on与where不同
以下的文章主要讲述的是MySQL关联left join 条件on与where 条件的不同之处,我们现在有两个表,即商品表(products)与sales_detail(销售记录表).我们主要是通过这两 ...