kotlin flowlayout

高级UI

自定义 flowLayout 流失布局,主要是两个方法重写

a、onMeasure(int, int)  确定所有子元素的大小  
b、onLayout(boolean, int, int, int, int)  View分配所有的子元素的大小和位置

github地址: https://github.com/haoda2328/flowLayout

 /**
     * 记录所有行的 view 集合
     */
    private var alls: ArrayList<ArrayList<View>> = ArrayList()

    /**
     * 临时记录每一行的 view 集合
     */
    private var lines: ArrayList<View?> = ArrayList()

    /**
     * 子类布局的 LayoutParams
     */
    private var params: RelativeLayout.LayoutParams? = null

    /**
     * 测量布局大小
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //重新计算时数据 归零
        alls.clear()
        lines.clear()
        //子类 View
        val count = childCount
        if (count == 0) {
            return
        }
        //需要计算出来的宽、高值
        var width = 0
        var height = 0

        //根据父类计算出 当前flowlayout 的 大小值(参考作用)
        val selftWidth = MeasureSpec.getSize(widthMeasureSpec)
        val selfHeight = MeasureSpec.getSize(heightMeasureSpec)

        //根据父类计算出  MeasureSpec  mode
        val modeWidht = MeasureSpec.getMode(widthMeasureSpec)
        val modeHeight = MeasureSpec.getMode(heightMeasureSpec)

        for (i in 0 until count) {
            params = getChildAt(i).layoutParams as LayoutParams?
            val childWidthMeasureSpec = params?.width?.let {
                getChildMeasureSpec(
                    widthMeasureSpec
                    , paddingLeft + paddingRight, it
                )
            }
            val childHeightMeasureSpec = params?.height?.let {
                getChildMeasureSpec(
                    heightMeasureSpec
                    , paddingTop + paddingBottom, it
                )
            }
            //子类测量
            childWidthMeasureSpec?.let {
                childHeightMeasureSpec?.let { it1 ->
                    getChildAt(i).measure(
                        it,
                        it1
                    )
                }
            }
            val childWidth = getChildAt(i).measuredWidth
            val childHeigth = getChildAt(i).measuredWidth

            width += childWidth
            if (width > selftWidth - paddingLeft - paddingRight) {
                width = 0
                alls.add(lines.clone() as java.util.ArrayList<View>)
                lines.clear()
            }
            lines.add(getChildAt(i))
        }
        alls.add(lines.clone() as java.util.ArrayList<View>)
        if (alls.size > 1) {
            width = selftWidth
            height =
                alls.size * (getChildAt(0).measuredHeight + paddingBottom + paddingTop)
        } else {
            width = getChildAt(0).measuredHeight
        }

        width = when (modeWidht) {
            MeasureSpec.AT_MOST -> {
                width
            }
            MeasureSpec.UNSPECIFIED -> {
                width
            }
            MeasureSpec.EXACTLY -> {
                selftWidth
            }
            else -> {
                width
            }
        }
        when (modeHeight) {
            MeasureSpec.AT_MOST -> {
            }
            MeasureSpec.UNSPECIFIED -> {
            }
            MeasureSpec.EXACTLY -> height = selfHeight
        }

        Log.i("layoutParams", "width == $width height == $height")
        setMeasuredDimension(width, height)

    }

    /**
     * 显示位置计算
     */
    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        if (alls.size == 0) {
            return
        }
        var top = paddingTop
        for (i in alls.indices) {
            val mtop = alls[0][0].measuredHeight
           var left = paddingLeft
            val datas = alls[i]
            for (j in datas.indices) {
                val view = datas[j]
                val mleft = view.measuredWidth
                view.layout(left, top, left + mleft, top + mtop)
                Log.i("layoutParams", "left == $left ")

                //宽度 累加计算
                left += mleft
                //换行 时高度 累加计算
                if (j == datas.size - 1) {
                    top += mtop
                }
            }
        }
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值