Android中常见的自定义FlowLayout流式布局的使用
在日常的app使用中,我们会在Android 的app中看见,比如淘宝购物页面尺寸的选取,脉脉和慕课技术职位的选取等等热门标签自动换行的流式布局,今天,我们就来看看如何自定义一个类似热门标签那样的流式布局吧,老规矩,直接上效果图
概述
1.流式布局原理:
在布局内,随意摆放任意个view,每行所摆放的view个数,根据实施计算出来的宽度,一旦当前要摆放的view宽度和之前摆放的所有view宽度加在一起,超过了布局的宽度,那么就把该view换行摆放
2.应用场景:
一般,像这种流式布局会应用在一些热门标签,热门推荐之类的应用上
3.测量模式:
谈到FlowLayout流式布局,不得不提及他的测量模式:
* MeasureSpec.EXACTLY:精确模式, eg:100dp,match_parent.(明确指出)
* MeasureSpec.AT_MOST: 至多模式, view最多可以获得的宽高值,它需要计算所有包含的子view的宽高,最后计算出来的宽高总和值,eg:wrap_content.
* UNSPECIFIED:未指定模式,想设置多宽多高,就给你多宽多高,一般的控件不会指定这种模式,但也存在,这种模式用的不多。eg:scrollview的宽高测量,就是使用的此种模式
4.在我们的流式布局内,应该怎么设置布局的宽高呢? onMeasure()
1:如果布局指定的宽是match_parent或者精确的宽度值,那么直接就可以从父控件传入的测量规格中直接获取布局宽度,高度同理.
2:如果布局指定的宽高不是EXACTLY,而是AT_MOST,那么这时候,就需要计算每一个子view的宽高,来决定布局的宽高了。
宽度:摆放的所有子view占据宽度最多的一行,作为布局宽度。
高度:摆放的所有子view总共占据几行的高度总和。
5.子View的布局方式: onLayout()
使用onLayout():设置ViewGroup内包含的所有子view的位置;
获取到每一行的每一个子view,计算出它的left,top,right,bottom,调用layout方法设置其在流式布局当中的位置。
宽度=子view最多的那行的宽度=那一行每一个子view的宽度+leftMargin+rightMargin;
高度=所有行的高度 = 每一行的高度+topMargin+bottomMargin;
LayoutParams参数的设置
ViewGroup LayoutParams :每个 ViewGroup 对应一个 LayoutParams; 即 ViewGroup -> LayoutParams
getLayoutParams 不知道转为哪个对应的LayoutParams ,其实很简单,就是如下:
子View.getLayoutParams 得到的LayoutParams对应的就是 子View所在的父控件的LayoutParams;
例如,LinearLayout 里面的子view.getLayoutParams ->LinearLayout.LayoutParams
所以 咱们的FlowLayout 也需要一个LayoutParams,由于上面的效果图是子View的 margin,
所以应该使用MarginLayoutParams。即FlowLayout->MarginLayoutParams
自定义ViewGroup的实现流式布局
根据上面的技术分析,自定义类继承于ViewGroup,并重写 onMeasure和on