Android视图绘制流程

参考:https://blog.csdn.net/guolin_blog/article/details/16330267

一、onMeasure()

  • 测量视图的大小:从ViewRoot的perform Traversals()方法中开始,在内部调用View的measure()方法

    • measure()方法会接收两个参数

      • widthMeasureSpec

      • heightMeasureSpec

      • 这两个参数是父视图计算后传递给子视图的

        • 最外层的根视图的两个参数是通过getRootMeasureSpec(desiredWindowWidth, lp.width);方法设置的

        • lp.width和lp.height在创建ViewGroup时就被赋值为match_parent

        • getRootMeasureSpec会返回EXACTLY

          • 即根视图总是充满全屏的

    • measure方法是final的,无法在子类重写,其中onMeasure方法是真正测量并设置View大小的地方

  • MeasureSpec的值由specSize和specMode共同组成

    • specSize:大小

    • specMode:规格

      • EXACTLY:固定、match_parent

      • AT_MOST:wrap_content

      • UNSPECIFIED:一半不太会用到

    • measureSpec是一直从measure()方法中传递过来的,然后调用MeasureSpec.getMode()解析出specMode

二、onLayout()

  • 给视图进行布局,确认视图的位置,ViewRoot的performTraversals()方法会在measure结束后继续执行,并调用View的layout()方法来执行此过程

    • layout()方法接收上下左右四个参数

      • 收线调用setFrame()方法来判断视图的大小是否发生过变化,以确定有没有必要重绘

      • 调用onLayout()方法,目的是确认视图的位置

  • 实际上这个操作时ViewGroup中的onLayout()来完成

    • ViewGroup中的onLayout()是一个抽象方法,子类自己去实现

  • onLayout()结束后,可以调用getWidth()和getHeight()去获取视图的宽高了

  • getWidth()和getMeasureWidth()区别

    • getMeasureWidth在measure结束后就可以获取到,getWidth要在layout()以后才能获取到

    • getMeasureWidth的值是通过setMeasuredDimension()方法设置的,getWidth是通过视图右边坐标减去左边左边计算出来的

三、onDraw()

  • ViewRoot会创建一个Canvas对象,然后调用View的draw()方法来执行具体的绘制工作

    • 首先绘制背景

      • 此处会得到一个mBGDrawable对象

      • 然后根据layout过程确定的视图位置来设置背景的绘制区域

      • 然后调用Drawable的draw方法来完成背景的绘制工作

    • 对视图的内容进行绘制

      • 调用了onDraw方法,交给子类去实现

    • 对当前视图的所有子视图进行绘制

      • view中的dispatchDraw方法也是空方法,ViewGroup的dispatchDraw方法中有具体的绘制代码

    • 对视图的滚动条进行绘制

      • 任何一个视图都有滚动条,只不过一般不显示出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值