美文网首页
Android View 的绘制流程(二)

Android View 的绘制流程(二)

作者: 刘小厨 | 来源:发表于2020-03-22 20:50 被阅读0次

    承接上篇文章Android View的绘制流程(一)

    这篇承接上篇,主要说下View绘制流程的具体细节核心方法

    • \color{blue}{measure() }
    • \color{blue}{layout () }
    • \color{blue}{draw () }

    下面依次分析

    \color{blue}{measure() }

    其实\color{blue}{measure() }的一系列操作,只做了一件事,就是赋值\color{blue}{measureWidth }\color{blue}{measureHeight},就是确定控件的测量宽高,在测量确定宽高的时候,我们要理解一个很重要的概念:\color{red}{MeasureSpec }

    \color{blue}{MeasureSpec } = 模式 + 尺寸

    MeasureSpec 是对View宽高属性的封装,是一个32位的int值,前两位表示模式,后30位表示尺寸 及SpecModel+SpecSize
    View中定义了三个SpecModel常量,名字和含义分别为:

    public static final int UNSPECIFIED = 0 << MODE_SHIFT; 00000000000000000000000000000000
    

    父容器不对View做任何限制,一般是系统内部使用

    public static final int EXACTLY     = 1 << MODE_SHIFT; 01000000000000000000000000000000
    

    父容器检测出View的大小,View的大小就是SpecSize 对应布局属性LayoutPamras match_parent以及固定大小

    public static final int AT_MOST     = 2 << MODE_SHIFT; 10000000000000000000000000000000
    

    父容器指定一个可用大小,View的大小不能超过这个值,LayoutPamras wrap_content

    ViewGroup和View测量确定宽高的流程:

    ViewGroup measure --> onMeasure(测量子控件的宽高)--> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)

    View measure --> onMeasure --> setMeasuredDimension -->setMeasuredDimensionRaw(保存自己的宽高)

    注: 在自定义View时候,一定要重写onMeasure方法,否则View在布局中设置wrap_contentmatch_parent效果一样,自定义View要重写onMeasure方法重新确定自己的宽高,自定义ViewGroup要重写onMeasure确定子控件宽高,从而确定自身的宽高
    详见Android自定义View的wrap_content无效?

    \color{blue}{Layout() }

    layout方法主要是确定控件的左上右下的值,主要逻辑在View的setFrame()方法中实现
    ViewGroup layout(来确定自己的位置,4个点的位置) -->onLayout(进行子View的布局)
    View layout(来确定自己的位置,4个点的位置)

    layout方法还调用了自身的onLayout()方法,这个方法在View中是一个protected的空方法,供子类实现,

    • 如果子类是ViewGroup可以实现该方法布局子View
    • 如果子类是View,可以不实现

    \color{blue}{Draw() }

    draw方法主要做了以下事情

         *      1. Draw the background   绘制背景
         *      2. If necessary, save the canvas' layers to prepare for fading 如果需要进行图层的保存
         *      3. Draw view's content 绘制自身的内容
         *      4. Draw children 绘制子控件 dispatchDraw()方法
         *      5. If necessary, draw the fading edges and restore layers 
         *      6. Draw decorations (scrollbars for instance) 绘制装饰
    

    综上: 在自定义View的过程中需要重写以下方法:
    onMeasure()-> onLayout()->onDraw()
    如果自定义View是个容器,那么 onLayout()重写之后确定子View的布局,如果是个View,可以不重写这个方法,onDraw()是个可选项,比如重写的View中包含的都是系统控件,可以选择不重写这个方法.

    相关文章

      网友评论

          本文标题:Android View 的绘制流程(二)

          本文链接:https://www.haomeiwen.com/subject/nxevyhtx.html