前言

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

由于 子项(子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. 常用代码之四:创建jason,jason转换为字符串,字符串转换回jason,c#反序列化jason字符串的几个代码片段

    1.创建jason,并JSON.stringify()将之转换为字符串. 直接使用var customer={}, 然后直接customer.属性就可以直接赋值了. 也可以var customer = ...

  2. Android SDK Manager详解

    Android基础知识——Android SDK Manager详解   做Android开发时,免不了使用Android SDK Manager,安装需要的sdk版本.buildTools版本等等. ...

  3. 解决Myeclipse中导入自定义的配色方案后,JSP中的js代码块为白色背景的问题

    捣鼓了大半个上午,终于搞定.这样设置就可以了: 点击MyEclipse上方的菜单栏中的window菜单.选择Preferences菜单项.在弹出的窗口的左侧树形菜单依次选择:MyEclipse.Fil ...

  4. MySql计算两个日期的时间差函数

    MySql计算两个日期时间的差函数: 第一种:TIMESTAMPDIFF函数,需要传入三个参数,第一个是比较的类型,可以比较FRAC_SECOND.SECOND. MINUTE. HOUR. DAY. ...

  5. js关闭当前页面和给子页面的对象赋值

    代码如下: function saveData(){ //给父页面的对象赋值 frameElement.api.opener.document.getElementById("userNam ...

  6. 找不到dubbo:annotaion错误

    dubbo 2.8.4 出现找不到dubbo:annotation的错误,其实这个不会影响程序正确的运行,但是看到有红叉心里肯定非常不爽: 解决办法是,将dubbo-2.8.4.jar包,后缀改成.z ...

  7. 定期删除elasticsearch 的index 索引

    #!/bin/bashfind /data/elasticsearch/data/pro-kz-log/nodes/0/indices/ -type d -mtime +7 | awk -F" ...

  8. 定时删除elasticsearch的index

    #!/bin/bashfind /data/elasticsearch/data/kz-log/nodes/0/indices/ -type d -mtime +5 |  awk -F"/& ...

  9. 高精度运算库gmp

    网址:www.gmplib.org 我下载的是 6.1.2版本:https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2 执行操作如下: 1. tar -jv ...

  10. tips:解决bootstrap-switch 在jqgrid中动态加载不显示的问题

    bootstrapo-switch 是一个十分好用的插件,用来关闭开启再好不过了,适合状态类型只有两种的情况下可以进行切换 在使用中,在jqgrid动态加载的时候出现不能加载的问题 原因是html代码 ...