我是靠谱客的博主 直率钻石,最近开发中收集的这篇文章主要介绍Android自定义控件之onMeasure详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  在Android开发中往往需要根据需求对原生控件进行自定义,其中主要涉及到的就是onMeasure,onLayout和onDraw三个方法的重写与使用,其中onMeasure是其中最复杂的一个方法,很多程序员仅仅知道该方法用来测量大小,却不知道何时调用,如何去用,本文就对利用Linearlayout的源码来解析onMeasure.

 1.何时调用onMeasure

  onMeasure方法的作用时测量空间的大小,什么时候需要测量控件的大小呢?这个过程就同炒菜一样,在炒的时候你不需要考虑需要多少大小,只有你需要拿盘子装时,你才需要知道到底有多少菜,需要拿多大的盘子.             

    简单自定义Layout,和View并打出Log如下:

    由上图可以看出调用先后顺序是先调用父容器的onMeasure后调用View的onMeasure,实际上控件在创建时不需要知道大小,只需要先创建出在放入父容器时,父容器需要知道View大小时才去测量View的大小,接下来从源码来分析整个过程.

2.源码分析onMeasure调用

我们从LinearLayout的onMeasure为入口,开始分析整个过程:

    到这里先说明一下widthMeasureSpec和heightMeasureSpec这两个参数,两者实际是一样的,我们就用前者来说明,widthMeasureSpec用int值来表示,这个值由高32位和低16位组成,高32位保存的值叫specMode,可以通过如代码中所示的MeasureSpec.getMode()获取;低16位为specSize,同样可以由MeasureSpec.getSize()获取

    specMode组成与具体意义:

    这里就不过多解释,如果需要深入的同学请自行百度官方文档说明.
    接下来跟进看measureVertical方法,整个方法都在测量垂直方向的最终高度的值,该方法具体代码较长下面就展示关键代码:

      上面代码外面还有一个For循环包裹,循环次数是子View的数量,我们主要分析的事onMeasure的调用过程所以我们就不仔细解释代码,这里我们直接看measureChildBeforeLayout方法:
    最后实际调用的是getChildMeasureSpec方法获得View的宽和高的spec,最后调用View的measure方法,这里我们先看getChildMeasureSpec方法:

    这个方法传入三个参数,分别是ViewGroup的spec,可利用的最大宽度/高度,和View的宽度/高度,以上就是通过ViewGroup的model,view的宽度/高度综合比较最后生成一个spc.view的宽度/高度的值主要分三种情况-1表示match_parent,-2表示wrap_content,和具体数值(需要大于等于0),具体过程总结为下表(盗用一下别人的表格):
     从这个表我们能看出来,当View没有具体大小时,其大小最后都与ViewGroup的大小一致,这也就解释了为什么自定义的View的wrap_content没有效果,View的大小不完全由其父View决定,还由自身的onMeasure方法决定.
    最终利用MeasureSpec. makeMeasureSpec(resultSize, resultMode)生成一个int的spc,最后调用View的measure方法,将子View的spc传进去,下面我们看measure方法:

    方法较长我们也不具体分析,看黄字部分,在这个方法最后调用了自身的onMeasure方法并将widthMeasureSpc传入,这也就是View中的onMeasure中两个参数的由来.
    以上就是在自定义View是onMeasure方法的具体调用过程,由于我们分析的是过程所以没有具体分析实现,希望对大家理解整个过程又一定的帮助,有错误也请及时指出.

 
 

最后

以上就是直率钻石为你收集整理的Android自定义控件之onMeasure详解的全部内容,希望文章能够帮你解决Android自定义控件之onMeasure详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部