自定义ViewGroup之TagLayout

2020-07-25  本文已影响0人  卖炭少年炭治郎
package com.okay.mvdemo

import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import kotlin.math.max

/**
 * @author : zyl
 * @desc :
 */
class TagLayout(context: Context?, attrs: AttributeSet?) : ViewGroup(context, attrs) {

    private val childBounds = arrayListOf<Rect>()

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var widthUsed = 0
        var heightUsed = 0
        var lineWidthUsed = 0
        var lineMaxHeight = 0
        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSpecSize = MeasureSpec.getSize(widthMeasureSpec)
        for ((index, child) in children.withIndex()) {
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, heightUsed)
           //保证每个子view只会创建一个rect
            if (index >= childBounds.size) {
                childBounds.add(Rect())
            }
            //如果是UNSPECIFIED 拿不到具体宽度值
            if (widthSpecMode != MeasureSpec.UNSPECIFIED && widthSpecSize < lineWidthUsed + child.measuredWidth) {
                //需要折行
                heightUsed += lineMaxHeight
                lineWidthUsed = 0
                lineMaxHeight = 0
                //折行之后已用高度变了 所以需要重新测量
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, heightUsed)
            }
            val rect = childBounds[index]
            rect.set(
                lineWidthUsed,
                heightUsed,
                lineWidthUsed + child.measuredWidth,
                heightUsed + child.measuredHeight
            )
            lineWidthUsed += child.measuredWidth
            widthUsed = max(lineWidthUsed,widthUsed)
            lineMaxHeight = max(lineMaxHeight, child.measuredHeight)
        }

        val selfWidth = widthUsed
        val selfHeight = lineMaxHeight + heightUsed
        setMeasuredDimension(selfWidth, selfHeight)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        for ((index, child) in children.withIndex()) {
            val childBound = childBounds[index]
            child.layout(childBound.left, childBound.top, childBound.right, childBound.bottom)
        }
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }


}
上一篇下一篇

猜你喜欢

热点阅读