流式布局,好处就是父类布局可以自动的判断子孩子是不是需要换行,什么时候需要换行,可以做到网页版的标签的效果。今天就是简单的做了自定义的流式布局。
具体效果:

原理:
其实很简单,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标签流式布局的功能,正好一直说给大 ...
随机推荐
- ionic4 添加自定义字体图标
在angular.json中的style中引入css文件: 然后在variables.scss中添加内容:
- Adobe Fireworks CS5 | Adobe Dreamweaver CS5 | Adobe Photoshop CS5 Extended 绿色精简版最新下载地址
下载地址可能已经不能直接下载,可以用迅雷下载试试 Adobe Photoshop CS5 简体中文绿色版 下载地址:Adobe_Photoshop_CS5_Extended.7z 此绿色版特点:1. ...
- apache shiro学习笔记
一.权限概述 1.1 认证与授权 认证:系统提供的用于识别用户身份的功能,通常登录功能就是认证功能-----让系统知道你是谁?? 授权:系统授予用户可以访问哪些功能的许可(证书)----让系统知道你能 ...
- web 服务器安全防范
apache 关闭目录 配置文件:安装目录/Apache/conf/httpd.conf <Directory /> #默认就会把/ 的目录暴漏出来:关闭方法: Options -Inde ...
- Tensorlflow-解决非线性回归问题
import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt #使用numpy生成200个随机点,范围从-0.5到0 ...
- ACM自己之前寒假的基础总结
1.const double pi = acos(-1.0); acos:反余弦函数,需要#include<math.h>函数库,acos(-1.0)的意思就是求π的值 2.算法竞赛中,不 ...
- 1076 Wifi密码 (15 分)
下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1:B-2:C-3:D-4:请同学们自己作答,每两日一 ...
- PIE SDK 坐标系创建、定义、对比
1. 坐标系创建 1.1 从WKT字符串导入空间参考 ISpatialReference接口是一个任何空间参考对象都实现的接口,它包含了所有空间参考对象都公有的方法和属性,如获得空间参考对 ...
- vm12下Centos6安装mysql5.7
一.下载mysql的rpm tar文件 文件名称:mysql-5.7.18-1.el6.x86_64.rpm-bundle.tar官方地址:https://dev.mysql.com/get/Down ...
- Ionic3,懒加载(二)
Ionic懒加载: 普通的ionic项目中,创建好每一个Component页面后,都需要在app.module.ts中进行declaration(声明)后才能进行调用,而这样的声明方式,及在APP加载 ...