专栏名称: 开发者全社区
分享和推送Java/Android方向的技术和文章,让你成为这方面的大牛,让你每天都成长一点。同时,我们也会邀请BAT的大牛分享原创!
目录
相关文章推荐
鸿洋  ·  掌握这17张图,掌握RecyclerView ... ·  2 天前  
郭霖  ·  Android - 监听网络状态 ·  6 天前  
鸿洋  ·  5种常见Gradle依赖版本管理指南 ·  6 天前  
51好读  ›  专栏  ›  开发者全社区

Android自定义View—实现流式布局(热门标签效果)

开发者全社区  · 公众号  · android  · 2017-01-14 11:41

正文

相关阅读:

吊炸天!74款APP完整源码!

123个微信小程序源码分享(附下载)

一个Android项目搞定所有主流架构:MVP+单元测试


效果图


实现效果图

思维导图


思维导图

一、流式布局的实现

实现原理:采用面向对象思想将整个布局分为很多行的对象,每个行对象管理自己行内的孩子,这里通过集合来管理。

1. 内部类Line的实现

1.1 定义行的基本属性
  • List:管理行中的孩子

  • maxWidth:行的最大宽度

  • usedWidth:使用的宽度

  • height:行的高度

  • space:孩子之间的间距

  • 构造初始化maxWidth和space


1.2 addView(View view)方法实现
  • 往行的集合里添加View,更新行的使用宽度和高度


1.3 canAddView(View view)方法实现
  • 判断是否能往行里添加孩子,如果孩子的宽度大于剩余宽度就不能


2. 对容器进行测量(onMeasure方法的实现)

2.1 获取宽度,计算maxWidth,构造传入Line
  • 总宽度减去左右边距就是行的最大宽度


2.2 循环获取孩子进行测量
  • 获取孩子总数,遍历获取每一个孩子,然后进行测量,测量完之后还需要将孩子添加到行集合里,然后将行添加到管理行的集合里


2.3 测量自己

  • 由于宽度肯定是填充整个屏幕,这里只需要处理行的高度,累加所有的行高和竖直边距算出高度


3. 指定孩子的显示位置(onLayout方法的实现)

实现思路:指定孩子的位置,孩子给了行管理,所以这里具体孩子的位置应该交给行去指定。容器只需要指定行的位置就可以。

  • 遍历获取所有的行,让行去指定孩子的位置,指定行的高度


4. Line中layout方法的实现(指定孩子的位置)

  • 遍历获取每一个孩子,获取孩子的宽度和高度,计算上下左右的大小,指定孩子的位置,之后还需要更新孩子左边的大小


5. 细节处理

  • 第一次测量之后,行管理器中就有了行的对象,之后每次测量都会去创建下一行,这样就会出现很多空行出来,所以需要在测量之前将集合清空。

      mLines.clear();
      mCurrentLine = null;
  • 每一行的最后一个孩子放不下就放到下一行,这样每一行就都会有空格,这里将这些空格平分给行里的每一个孩子,重新指定其宽度。


6. 使用自定义属性,将水平间距和竖直间距做成属性,在布局中指定,增强扩展性

  • attrs文件指定属性名

     name="FlowLayout">
          name="width_space" format="dimension"/>
          name="height_space" format="dimension"/>
     
  • 构造中获取属性


  • 布局中使用属性

      app:width_space="10dp"  app:height_space="10dp"
经过以上步骤之后,FlowLayout基本就已经实现了,接下来就是使用了。

二、流式布局的使用

  • 布局中申明

      "http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:fillViewport="true"
          tools:context="com.pinger.sample.MainActivity">
    
          .pinger.library.FlowLayout
              app:width_space="10dp"
              app:height_space="10dp"
              android:id="@+id/flow_layout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:padding="5dp"/>
      
  • 代码中使用

  • 其实就是循环遍历数据的长度,不断的创建TextView,然后设置TextView的属性和背景,包括五彩背景等,最后将TextView添加到FlowLayout中就可以。

  • 具体代码请查看Demo

  • 个人主页

  • 演示Demo下载

  • 文/敲代码的大圣

  • 原文鏈接:http://www.jianshu.com/p/0e12a1214e62


关于Java和Android大牛频道

Java和Android大牛频道是一个数万人关注的探讨Java和Android开发的公众号,分享和原创最有价值的干货文章,让你成为这方面的大牛!

我们探讨android和Java开发最前沿的技术:android性能优化 ,插件化,跨平台,动态化,加固和反破解等,也讨论设计模式/软件架构等。由群来自BAT的工程师组成的团队

关注即送红包,回复:“百度” 、“阿里”、“腾讯” 有惊喜!!!关注后可用入微信群。群里都是来自百度阿里腾讯的大牛。

欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。搜索微信公众号:JANiubility。

公众号:JANiubility