自定义Viewgroup实现流式布局(3):实现流式布局

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值