前言

实际项目中需要实现一个 热门搜索 的栏目,类似下图:

由于 子项(子view) 中的文字是可变的,一行能显示的 子项 的个数也无法确定。需要支持自动换行和计算位置。

开源类库

我自己写了个 自定义view ,继承自viewGroup, 来实现它,托管到github开源平台。

名称:SimpleFlowLayout

地址:https://github.com/vir56k/SimpleFlowLayout

特点:可以不断添加多个子view,计算位置,自动换行。 类似html中的div标签

适用: 热门标签

实现思路

 要实现 自定义的viewgroup,需要:

1. 继承自 ViewGroup

2. 实现 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

  这个方法用于测量 自己(自定义view)本身需要的宽度和高度

3. 实现 protected void onLayout(boolean changed, int l, int t, int r, int b)

  这个方法用于指定如何摆放 子view 的位置。

实现代码

package zhangyf.vir56k.flowframelayout;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup; /**
* name: android 简单的流布局自定义view
* 作者:张云飞
* 特点:可以不断添加多个子view,计算位置,自动换行。
* 适用: 热门标签
* Created by zhangyunfei on 15/12/4.
*/
public class SimpleFlowLayout extends ViewGroup {
public SimpleFlowLayout(Context context) {
super(context);
} public SimpleFlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
} public SimpleFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMax = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMax = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthNeed = 0;
int heightNeed = 0;
int x = 0;
int y = 0;
int currentLineHeight = 0;
View child;
for (int i = 0; i < getChildCount(); i++) {
child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
} child.measure(widthMeasureSpec, heightMeasureSpec);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();//获得子view的 外边距
//测算子view宽度,本行这句代码有问题,不能计算子view的自动换行 int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
//使用viewGroup的measureChildWithMargins测算宽度,在这个方法里处理了 LayoutParams的match_parent等方式的处理
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; if (x + childWidth > widthMax) {//换行处理,本行高度和x轴都清零,y轴下移(加上上次的行高)
y += currentLineHeight;
currentLineHeight = 0;
x = 0;
}
x += childWidth;
currentLineHeight = Math.max(currentLineHeight, childHeight); widthNeed = Math.max(widthNeed, x);//加入了这个 子view后,留下最大宽度
heightNeed = Math.max(heightNeed, y + currentLineHeight);//对比上次的,留下最大的高度
}
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthMax : widthNeed,
heightMode == MeasureSpec.EXACTLY ? heightMax : heightNeed);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int widthMax = getWidth();
int x, y;
x = 0;
y = 0;
View child;
int left = 0;
int top = 0;
int currentLineHeight = 0;
for (int i = 0; i < getChildCount(); i++) {
child = getChildAt(i);
if (child.getVisibility() == View.GONE) {
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if (x + childWidth > widthMax) {//换行处理
y += currentLineHeight;
x = 0;
currentLineHeight = 0;
}
left = x + lp.leftMargin;
top = y + lp.topMargin;
//定位子view的位置
child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight()); x += childWidth;
currentLineHeight = Math.max(currentLineHeight, childHeight);
}
} @Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
} }

  

android 自定义流布局。实现热门标签。开源库SimpleFlowLayout的更多相关文章

  1. Android 自定义View修炼-Android中常见的热门标签的流式布局的实现

    一.概述:在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出哈) 类似的 ...

  2. Android(常用)主流UI开源库整理

    这几天刚做完一个项目..有点空余时间,就想着吧这一两年做的项目中的UI界面用到的一些库整理一下.后来想了一下,既然要整理,就把网上常用的 AndroidUI界面的主流开源库 一起整理一下,方便查看. ...

  3. iOS 热门高效开源库集锦,收藏备用

    一.推荐使用的第三方库 1:基于响应式编程思想的ReactiveCocoa 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:iOS解耦与组件化开 ...

  4. Android控件进阶-自定义流式布局和热门标签控件

    技术:Android+java   概述 在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧,类 ...

  5. Android 开源库获取途径整理

    介绍眼下收藏 Android 开源库比較多的 GitHub 项目.站点.Twitter.App 及怎样获取最新的 Android 开源库. 微信号: 1. GitHub Android 开源项目汇总 ...

  6. android开源库发布到jcenter图文详解与填坑

    相信很多人都用过开源项目,特别是android studio普及以后,使用开源库更方便简单.而如何上传开源库到jcenter供大家方便使用,虽然网上也有教程,但还是遇坑了,最后总结一下,希望可以帮助大 ...

  7. Android 使用SwipeActionAdapter开源库实现简单列表的左右滑动操作

    我们做listview左右滑动操作时,一般中情况下,都是像QQ那样,左滑弹出操作菜单(删除.编辑),然后选择菜单操作: 这样的效果不可谓不好,算是非常经典. 另外,有少数的APP,尤其是任务管理类的A ...

  8. 粉笔网iPhone端使用的第三方开源库

    粉笔网iPhone端使用的第三方开源库 前言 最近有朋友问我粉笔网 iPhone 端使用了哪些第三方的开源库.我在这儿整理了一下,分享给大家. ASIHttpRequest ASIHttpReques ...

  9. Android主流UI开源库整理(转载)

    http://www.jianshu.com/p/47a4a7b99364 标题隐含了两个层面的意思,一个是主流,另一个是UI.主流既通用,一些常规的按钮.Switch.进度条等控件都是通用控件,因此 ...

随机推荐

  1. [转]PostgreSQL教程:系统表详解

    这篇文章主要介绍了PostgreSQL教程(十五):系统表详解,本文讲解了pg_class.pg_attribute.pg_attrdef.pg_authid.pg_auth_members.pg_c ...

  2. Excel列添加单引号

    ="'"&A2&"',"   对A2列同步添加单引号

  3. mysql 8.0给数据库添加用户和赋权

    -- 使用mysql 数据库 USE mysql -- 为mysql创建用户:case_dev 密码为:pass123 CREATE USER case_dev IDENTIFIED BY 'pass ...

  4. apiDoc自动生成api文档

    在自定生成api文档方面以前都是使用swagger.json结合swagger工具来生成文档,偶然发现了apidoc这个生成api的工具,发现使用起来比swagger更加简单,下面整理一下使用过程: ...

  5. Word 2010之简单图文混排

    所谓图文混排,就是指将图片与文本内容进行一定规律的排列,以让文档更加漂亮. 下面的示范是一个简单的将两副照片混排到文字当中的(图片与文本内容无关,仅供演示). 1. 打开Word,输入文本内容: 2. ...

  6. 在c/c++中浮点数是否为0的判断

    在c/c++中,因为浮点数在内存中的表示是不精确的,会有很微小的误差,所以判断是否为0,就看它的绝对值是不是<=eps. eps可以看成是epsilon的缩写,可以用来表示一个无穷小的量,通常取 ...

  7. MD5 和的价值体现在哪里,它是用来做什么的?

    MD5 和的价值体现在哪里,它是用来做什么的? MD5 和是由字母和数字构成的字符串,起到了文件指纹的作用.如果两个文件有相同的 MD5 和值,那么,文件完全相同.您可以为每一软件下载使用所提供的 M ...

  8. jQuery正则的使用

    转自:http://www.maiziedu.com/wiki/jquery/regular/ 基础正则 1.正则表达式的创建 a) var checkNum = /^[A-Za-z0-9]+$/; ...

  9. Vue.js 组件编码规范

    本规范提供了一种统一的编码规范来编写 Vue.js 代码.这使得代码具有如下的特性: 其它开发者或是团队成员更容易阅读和理解. IDEs 更容易理解代码,从而提供高亮.格式化等辅助功能 更容易使用现有 ...

  10. IE报错:The given path's format is not supported

    在使用FileUpload控件进行上传EXCEL文件时,本地调试上传无问题,但是发布之后报地址无效错误 一.出现这个错误的主要原因是,在本地上传图片的时候HttpPostedFileBase对象里面保 ...