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

具体效果:
原理:
其实很简单,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) ; 
        }

}

代码下载地址:
 百度网盘:  http://pan.baidu.com/s/1hqH1kFU 

来自为知笔记(Wiz)

附件列表

  • 123.gif

转载于:https://www.cnblogs.com/flyme2012/p/4264161.html

Android自定义之流式布局相关推荐

  1. 自定义 FlowLayout流式布局搜索框 加 GreenDao存取搜索记录,使用RecyclerView展示

    输入框布局的shape <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android ...

  2. android自定义流式布局思路,Android 自定义控件基础-流式布局

    什么是流式布局?其实我们在平时遇到过,只是有可能叫不出它的名字. 如图: 如上图,就是一个流式布局的样式. &esmp;这里,将记录一下怎么实现这个功能.其实实现这个功能的方法,就是自定义Vi ...

  3. Android自定义控件之流式布局

    效果图: 一.首先创建我 们的自定义流式布局 public class FlowLayoutView extends ViewGroup {public FlowLayoutView(Context ...

  4. 100行Android代码自定义一个流式布局-FlowLayout

    首先来看一下 手淘HD - 商品详情 - 选择商品属性 页面的UI 商品有很多尺码,而且展现每个尺码所需要的View的大小也不同(主要是宽度),所以在从服务器端拉到数据之前,展现所有尺码所需要的行数和 ...

  5. Android 实现FlowLayout流式布局(热门标签)

    先上效果图: 接着看代码实现: public class FlowLayout extends ViewGroup {protected DataSetObserver mDataSetObserve ...

  6. Android自定义组合布局,Android 流式布局 + 自定义组合控件

    自定义组合控件 package yanjupeng.bawei.com.day09.two; import android.content.Context; import android.util.A ...

  7. Android 自定义UI 实战 02 流式布局

    Android 自定义UI 实战 02 流式布局-- 自定义ViewGroup 第二章 自定义ViewGroup 流式布局 文章目录 Android 自定义UI 实战 02 流式布局-- 自定义Vie ...

  8. android自定义view流布局,Android控件进阶-自定义流式布局和热门标签控件

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

  9. 自定义View----滑动刻度尺与流式布局 实例(四)

    2019独角兽企业重金招聘Python工程师标准>>> 近在系统学习自定义View这一块的知识,前面几篇基本都是理论知识,这篇博客着重从实战来加强对自定义View的理解与运用.实现的 ...

  10. Android 自动换行流式布局的RadioGroup

    用法 使用FlowRadioGroup代替RadioGroup import android.content.Context; import android.util.AttributeSet; im ...

最新文章

  1. Python:numpy实现生成随机数,忽略warnings
  2. springmvc学习(小知识点整理)
  3. socket 编程的端口和地址复用
  4. 事务的传播性和隔离级别
  5. 把握人工智能命脉的有效方法
  6. 第九十六期:JavaScript 中的 4 个相等比较算法的介绍
  7. mysql log all sql_记录一次mysqlbinlog恢复过程
  8. Azure SQL性能调优实践
  9. RAC11g使用数据泵导入导出报ORA-6512,ORA-25306,ORA-39079错
  10. python使用rpa需要什么插件_使用Python制作ArcGIS插件基础篇——工具介绍
  11. MySQL数据库MyISAM与InnoDB存储引擎的比较
  12. 重置winsock目录解决不能上网的问题
  13. 通达OA 2013版和2013增强版两个版本开发的一些差异
  14. 自考计算机00051笔记,自考00051 管理系统中计算机应用自考资料笔记自考小抄.doc...
  15. 用python爬取之后发现果然如此,都说知乎的小姐姐漂亮
  16. markdown和marktop是啥关系?
  17. iPhone怎么设置自定义铃声?苹果可以设置自定义铃声吗?
  18. 英语语法之强调句和倒装
  19. 泛读论文:Person-reID 行人重识别合集
  20. python正则表达式查找(findall)

热门文章

  1. bzoj4987: Tree(树形dp)
  2. 超酷的 mip-infinitescroll 无限滚动(无限下拉)
  3. *-mapper.xml配置文件
  4. WebGL难以置信的神奇效果
  5. STM32标准库官网下载方法
  6. 4.熟悉App Inventor 2编程界面
  7. Python 执行主程序
  8. Python基础七(深浅copy以及int,str,tuple,list,dic补充)
  9. Android—Socket服务端与客户端用字符串的方式互相传递图片
  10. DAG镶嵌模型+原始路径打印