View Measure Layoout Draw

measure过程决定了View的宽度和高度,Measure完成之后,可以通过getMeasureWidth和getMeasureHeight得到View的宽度和高度,一般情况下它都等于View的最终的宽高。

在测量的过程中,系统会将View的lauoutParams根据父VIew所施加的规则转换对应的MeasueSpec,然后在根据这个measureSpec来测量View的宽度和高度,该测量的宽和和高度只是测量的宽度和高度,不一定等于View的最终的宽度和高度。

 

一般q情况下View,其MeasureSpec有父View和自身的LayoutParams来共同决定

当View采用固定的宽度和高度的时候,不管父View的MeasureSpec是什么,View的最终MeasureSpec都是精确的模式,且大小遵循LayputParams中的大小。

当View的宽度和高度是match_parent时,如果父View是精确模式,那么View也是精确模式 并且大小是父View的剩余空间;如果父View是at_most模式,那么View也是at_most模式 且大小不会超过父容器的剩余空间。

当View的宽和高是wrap_content时,不管父View的模式是精确模式还是最大化,View的模式总是最大化 且大小不能超过父容器的剩余空间。

 

SpecMode

UNSPECIFIED

    父容器不对View施加限制,view需要多大就给多大,这种情况一般用在系统内部,表示一种测量状态。

EXACTLY

    父容器已经检测出View所需要的精确大小,这种情况下,View的大小最终就是SpecSize所指定的大小,它对应与LayoutParams中的match_parent和具体的数值

AT_MOST

    父容器指定了一个可用的大小即SpecSize,View的大小不能大于这个值,对应与Layoutparams中的wrap_content

 

void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

widthMeasureSpec、heightMeasureSpec是由父View传递进来的,其值是由父View的MeasureSpec和子View的lauoutParams共同决定的。

是由父View计算完成后 传递进来的。

 

view的MeasureWidth和MeasureHeight形成于measure过程中
view的最终width和height形成于layout过程中,通常这两个者是一样的,但是如果重写了layout方法就不一定相等了。

 

直接继承View的自定义控件需要重写onmeasure方法,并且设置wrap_content时的自身大小,否则在
布局中使用warp_content时 就相当于使用match_parent。因为在布局中使用wrap_content的时候,view的
SpecMode就是AT_MOST模式,在这种模式下,它的宽度和高度等于SpecSize,这种情况下View的SpecSize就是parentSize
,而parentSize是父View的目前可以使用的大小,也就是父View当前剩余的控件大小。很显然,View的宽和高就等于父
View当前剩余的控件大小,这种效果和在布局中使用match_parent完全一致。
处理模版代码:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSpecsize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSpecSize = MeasureSpec.getMode(heightMeasureSpec);

    if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(mWidth/*自定义控件的宽度大小*/, mHeight/*自定义控件高度大小*/);
    } else if (widthSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(mWidth/*自定义控件的宽度大小*/, heightSpecSize);
    } else if (heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(widthSpecsize, mHeight/*自定义控件高度大小*/);
    }
}

 

 

layout过程决定了View的四个顶点的坐标和实际的宽高【横坐标相减=宽度,纵坐标相减=高度】,layout完成之后,可以通过getTop,getBottom,getLeft,getRight来拿到View的

四个顶点的坐标,同时可以通过getWidth和getHight得到View的最终的宽度和高度。

 

draw过程决定了View的显示,draw完成之后 View才会显示在屏幕上

 

draw绘制过程:
1、绘制背景 background.draw(canvas)
2、绘制自身的内容 onDraw
3、绘制child (dispatchDraw)
4、绘制装饰

 

 


在自定义View的时候,如果是继承View实现的,那么如果不对View的wrap_content做处理,就相当于使用match_parent.
同时需要注意自己需要处理View的padding属性值。

 

 

 

图片转载:

自定义View分类:

 

 

自定义View须知:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值