自定义ViewGroup的基础记录

本文记录了自定义ViewGroup在Android开发中的关键步骤,包括`onMeasure()`方法中MeasureSpec的三种模式:EXACTLY、AT_MOST和UNSPECIFIED的解释,以及如何获取和设置自定义View的大小。接着讨论了`onLayout()`方法,重点介绍了如何使用`child.layout()`来布局子视图,并展示了简单的实现效果和数值变化的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

onMeasure()

        MeasureSpec 的三种模式:

                EXACTLY:确切大小

                AT_MOST:大小不能超过父布局,在这个值内,大小随着内容的大小而变化

                UNSPECIFIED:不对View大小做限制

获取当前给出的模式

val widthMode:  Int = MeasureSpec.getMode(widthMeasureSpec)
val heightMode:  Int = MeasureSpec.getMode(heightMeasureSpec)
logD(TAG," widthMode: $widthMode  heightMode: $heightMode")

logD(TAG,"MeasureSpec-   
    UNSPECIFIED: ${MeasureSpec.UNSPECIFIED} 
    , AT_MOST: ${MeasureSpec.AT_MOST} 
    , EXACTLY: ${MeasureSpec.EXACTLY} ")
        

/* 
   得到的数据分别是: 
        widthMode: 1073741824  heightMode: 1073741824
        UNSPECIFIED: 0 , AT_MOST: -2147483648 , EXACTLY: 1073741824
   所以当前MeasureSpec的模式是 EXACTLY 
   同时 1073741824 转换成十进制是 1050,也就是当前自定义View的所占的宽度
*/ 

// 1073741824

获取自定义View的总大小

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val widthSize: Int =  MeasureSpec.getSize(widthMeasureSpec)
        val heightSize: Int =  MeasureSpec.getSize(heightMeasureSpec)

       /*
            打出Log
                widthSize:1050 ,  heightSize: 1783
       */

完成简单的实现


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 获取模式和值
        val widthMode:  Int = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode: Int = MeasureSpec.getMode(heightMeasureSpec)
        val widthSize: Int =  MeasureSpec.getSize(widthMeasureSpec)
        val heightSize: Int =  MeasureSpec.getSize(heightMeasureSpec)
       
        //获取子view个数
        val childCount = childCount
     
        for (i in 0 until childCount) {
            // 获取单个子view
            val child = getChildAt(i)
            // 测量单个子view, 要求子view同规格大小的情况下,可以使用measureChildren()
            // child.measuredHeight是另一个数值,可以打印看下是多少
            measureChild(child, widthSize,child.measuredHeight)
        }
        // 测量自定义View的尺寸
        setMeasuredDimension( widthSize, heightSize )
    }

---------------------------------------------------------------------------------------------------------------------------------

onLayout

child.layout(左,上,右,下)

        用来对子view进行位置的摆放

完成简单的实现

        

override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) {
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            /*   (左,上,右,下)
                (450, 0, 1050, 500),则该View在距离父控件的左上角位置(455, 0)处显示,
                显示的大小是宽高是600, 500 (参数r,b是相对左上角的)
             */
            child.layout(450,0,1050,500)

        }
}

看下效果图

        

 

改变数值看下

// 将数值改变下,看下变化

 child.layout(450,0,1050,1500)

ok

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值