1.https://mp.csdn.net/postedit/87189294
2.https://mp.csdn.net/postedit/87189763
通过前面的1和2已经实现了简单的自定义viewgroup,流式布局和上一个换行的viewgroup相比:
需要判断一行上可以放置多少个子view;某一行view的实际高度是这一行最高的呢个view的高度;还需要考虑子view的margin属性。
支持margin:重写generateLayoutParams方法,返回new MarginLayoutParams对象。
1.根据传入的datas将子view add到viewgroup里面
正常使用肯定是在xml里面写<Flowlayout/>,代码写flowlayout.setData(),类似于listview那样;
那么addview就不能在构造器里面而是在onMeasure里面,而且onMeasure会执行多次,注意removeAllview;
2.onMeasure 计算多少行,每行都存放哪些子view以及viewgroup的宽高
计算子view的宽高,遍历子view,计算在哪换行等。使用List<List<View>> list 来存储所有view:外层list表示当前有多少行,内层表示每一行都是哪些子view。
3.onLayout显示view
遍历上面的list分别显示每一行,注意考虑margin。
4.子view点击事件并刷新显示
可以使用直接通过子view来控制也可以用数据源来控制。
(1.使用数据源来控制:点击事件的回调中对是否选中的bool值进行更改并调用requestLayout方法刷新显示,但是通过数据源来控制会频繁触发onMeasure和onLayout。这样做可以把控制单选和多选交给使用者通过数据源来处理
(2.使用子view控制:点击事件直接对数据源并更改只对子view更新显示,这样做控制单选和单选就必须在这个Viewgroup内部实现。
5.单选与多选
数据源控制的方式就不说了:点击事件修改数据源,然后requestLayout.
当子view控制时,多选在for循环addview的时候直接datas.get(i).setIsChoosed(!get(i).isChoosed)即可;
单选的时候就必须保证点击完整个view,其他的view全部变成未选中,变成未选中容易但是同时修改view对应的数据就有点麻烦。
两种方法处理:
(1.用add(view,index),这里的index就是getChildAt的index,通过判断getChildAt==点击事件的view,得到触发点击事件view在datas以及childs中对应的下标,for循环datas或者把childs不是这个下标的全部置false和设置不选中。
(2.这个点击事件本身就在datas的for循环内部,再for循环datas把除了这个下标外的所有数据全部置false,然后for循环childs判断当前点击view相等,不相等的全部设置不选中。
6.刷新数据
调用requestLayout方法重新走onmearsure方法
源代码地址:
https://github.com/15539158137/FlowLayoutDemo/tree/master
ViewGroup代码如下:
public class Flowlayout extends ViewGroup {
OnFlowlayoutItemClickListener onFlowlayoutItemClickListener;
public void setOnFlowlayoutItemClickListener(OnFlowlayoutItemClickListener onFlowlayoutItemClickListener) {
this.onFlowlayoutItemClickListener = onFlowlayoutItemClickListener;
}
public Flowlayout(Context context) {
super(context);
}
public Flowlayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Flowlayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public Flowlayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs