短视频平台源码,自定义流式布局--kotlin

短视频平台源码,自定义流式布局--kotlin实现的相关代码

一、使用原因

1.流式布局中放了许多小的view,要求我们把这些子view妥善的摆放在一个viewgroup中,如果我们在xmL中去实现这个效果,这就要求我们去对每个子view设置margin,padding,还有位置属性。这可能需要花很多时间去摆放,去设置。

2.如果我们做一个搜索内容的历史记录,那么我们事先是不知道子view的条目和具体内容的,所以我们也没法在XML中去书写,那么我们就需要一个viewgroup去对数据进行操作,取自动生成子view,并把他们的位置摆放妥当。

二、使用步骤

1.创建一个类继承viewgroup

代码如下:

 

class TagLayout(context: Context?, attrs: AttributeSet?) : ViewGroup(context, attrs)

2.重写onMeasure方法

 

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //摆放时所有子view占据的横向边界
        var widthUsed = 0
        //所有子view占据的纵向高度
        var heightUsed = 0
        //当前行的子view占据的宽度
        var lineWidthUsed = 0
        //当前行占据的纵向高度
        var lineMaxHeight = 0
        //拿到布局的期望宽度
        val widthMeasureSpecSize = MeasureSpec.getSize(widthMeasureSpec)
        for ((index, child) in children.withIndex()) {
            //给child进行测量
            measureChildWithMargins(
                child,
                widthMeasureSpec,
                0,
                heightMeasureSpec,
                heightUsed
            )
            //超出边界时换行
            if (child.measuredWidth + lineWidthUsed > widthMeasureSpecSize) {
                //累加这行的高度
                heightUsed += lineMaxHeight
                //新开一行,还没有子view,下面两个值置为零
                lineWidthUsed = 0
                lineMaxHeight = 0
                //由于新开了一行,则对子view进行重新测量
                measureChildWithMargins(
                    child,
                    widthMeasureSpec,
                    lineWidthUsed,
                    heightMeasureSpec,
                    heightUsed
                )
            }
            //如果存放子view对应位置的childrenBounds中还没有存放过这个子view的Rect,则进行添加,避免在onMeasure中对对象进行重复创建。
            if (index >= childrenBounds.size) {
                childrenBounds.add(
                    Rect()
                )
            }
            //设置child 的位置和大小
            childrenBounds[index].set(
                lineWidthUsed,
                heightUsed,
                lineWidthUsed + child.measuredWidth,
                heightUsed + child.measuredHeight
            )
            //把新加的子view的宽度进行累加
            lineWidthUsed += child.measuredWidth
            //更新已加入的所有子view占据的宽度
            widthUsed = max(widthUsed, lineWidthUsed)
            //更新当前行的view中最高的view高度,既这行子view所占据的高度
            lineMaxHeight = max(lineMaxHeight, child.measuredHeight)
        }
        //获取到所有子view占据的高度,因为最后一行的view高度没有在循环中进行累加,所有循环结束要记得加上
        val selfHeight = heightUsed + lineMaxHeight
        //获取所有子view占据的宽度
        val selfWidth = widthUsed
        setMeasuredDimension(selfWidth, selfHeight)
    }

 

小结

1.在onMeasure中测量每个子view的大小和位置,并用一个Rect的List用来记录,以供后面onlayout中使用,并且在测量完所有子view后得到viewgroup最合适的大小

2.该处使用0作为第三个参数widthUsed,这是为什么呢?

 

 measureChildWithMargins(
                child,
                widthMeasureSpec,
                0,
                heightMeasureSpec,
                heightUsed
            )

 

以上就是 短视频平台源码,自定义流式布局--kotlin实现的相关代码,更多内容欢迎关注之后的文章

 

posted @ 2021-12-06 14:17  云豹科技-苏凌霄  阅读(100)  评论(0编辑  收藏  举报