自定义View入门(01)
package com.focus.mimilive.widget.imggroup

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.qingshu520.common.utils.dp

/**
 *
 * @author: est7
 * @date: 2022/11/7
 */
class HorizontalImgGroup @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
    /**
     * 头像的半径
     */
    private val mRadius = 50.dp

    /**
     * 头像间的距离百分比
     */
    private var mBasis = 0.7


    /**
     * 最大头像数目
     */
    private var mMaxCount = 10

    init {
        //获取属性值,这里就不管这些了直接写死了
        //val attrsSet = context.obtainStyledAttributes(attrs, R.styleable.HorizontalImgGroup)
        //attrsSet.recycle()
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val heiMeasure = MeasureSpec.getSize(heightMeasureSpec)
        val widMeasure = MeasureSpec.getSize(widthMeasureSpec)
        val heiMode = MeasureSpec.getMode(heightMeasureSpec)
        val widMode = MeasureSpec.getMode(widthMeasureSpec)

        var wid = 0
        var hei = 0

        for (i in 0 until childCount) {
            val child: View = getChildAt(i)
            val lp: LayoutParams = child.layoutParams
            lp.width = 2 * mRadius
            lp.height = lp.width
            child.setLayoutParams(lp)
            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            val childWidth: Int = child.measuredWidth
            val childHeight: Int = child.measuredHeight


            if (i < mMaxCount) {
                // 计算宽度
                //一个的时候全宽,
                //n个的时候1 + mBasis *(count-1)
                wid = if (i == 0) {
                    wid + childWidth
                } else {

                    (wid + childWidth * mBasis).toInt()
                }
            }
            hei = Math.max(hei, childHeight)
        }
        //如果是exactly使用测量宽和高,否则使用自己设置的宽和高
        setMeasuredDimension(
            if (widMode == MeasureSpec.EXACTLY) widMeasure else wid,
            if (heiMode == MeasureSpec.EXACTLY) heiMeasure else hei
        )

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left = 0
        val top = 0
        var right = 0
        val bottom = 0
        //倒着摆放才能把第一个放最上面
        for (i in 0 until childCount) {
            var child = getChildAt(childCount - i - 1)
            val childWidth = child.measuredWidth
            val childHeight = child.measuredHeight
            right = if (i == 0) {
                right + childWidth
            } else {
                (right + childWidth * mBasis).toInt()
            }
            child.layout(left, top,right,childHeight)

            //left坐标更新
            left = (left + childWidth * mBasis).toInt()
        }
    }
}

package com.focus.mimilive.widget.imggroup

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.poppo.exolibrary.util.L
import com.qingshu520.common.utils.dp
import kotlin.text.Typography.half


/**
 *
 * @author: est7
 * @date: 2022/11/7
 */
class HorizontalImgGroup @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
    /**
     * 头像间的距离百分比
     */
    private var mBasis = 0.7

    /**
     * 最大头像数目
     */
    private var mMaxCount = 10

    init {
        //获取属性值,这里就不管这些了直接写死了
        //val attrsSet = context.obtainStyledAttributes(attrs, R.styleable.HorizontalImgGroup)
        //attrsSet.recycle()
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val heiMeasure = MeasureSpec.getSize(heightMeasureSpec)
        val widMeasure = MeasureSpec.getSize(widthMeasureSpec)
        val heiMode = MeasureSpec.getMode(heightMeasureSpec)
        val widMode = MeasureSpec.getMode(widthMeasureSpec)

        var wid = 0
        var hei = 0

        for (i in 0 until childCount) {
            val child: View = getChildAt(i)
            val lp: LayoutParams = child.layoutParams
            val min = lp.height.coerceAtMost(lp.width)
            lp.width = min
            lp.height = min
            child.layoutParams = lp
            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            val childWidth: Int = child.measuredWidth
            val childHeight: Int = child.measuredHeight


            if (i < mMaxCount) {
                // 计算宽度
                //一个的时候全宽,
                //n个的时候1 + mBasis *(count-1)
                wid = if (i == 0) {
                    wid + childWidth
                } else {

                    (wid + childWidth * mBasis).toInt()
                }
            }
            hei = Math.max(hei, childHeight)
        }
        //如果是exactly使用测量宽和高,否则使用自己设置的宽和高
        setMeasuredDimension(
            if (widMode == MeasureSpec.EXACTLY) widMeasure else wid,
            if (heiMode == MeasureSpec.EXACTLY) heiMeasure else hei
        )

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left = 0
        var top = 0
        var right = 0
        var bottom = 0

        var renderCount = childCount.takeIf { it < mMaxCount } ?: mMaxCount

        for (i in 0 until renderCount) {
            var child = getChildAt(i)

            val childWidth = child.measuredWidth
            val childHeight = child.measuredHeight
            right = if (i == 0) {
                right + childWidth
            } else {
                (right + childWidth * mBasis).toInt()
            }

            //设置层级
            if (i < renderCount / 2) {
                child.z = i.toFloat()  //1,2
            } else {
                child.z = renderCount - i.toFloat() - 1
            }

            child.layout(left, top, right, childHeight)
            left = (left + childWidth * mBasis).toInt()
        }

        
    }

}
    <HorizontalImgGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@color/green_point"
            android:text="1111">

        </TextView>

        <TextView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@color/red"
            android:text="1111">

        </TextView>

        <TextView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="@color/yellow_1"
            android:text="1111">

        </TextView>


        <TextView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@color/green_point"
            android:text="1111">

        </TextView>


        <TextView
            android:layout_width="100dp"
            android:layout_height="1000dp"
            android:background="@color/red"
            android:text="1111">

        </TextView>

    </HorizontalImgGroup>
posted on 2022-12-28 19:48  7m  阅读(18)  评论(0编辑  收藏  举报