Connor学Android - View绘制流程

在这里插入图片描述

Learn && Live

虚度年华浮萍于世,勤学善思至死不渝

前言

Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/Vt8Re,话不多说我们马上开始!

1.View绘制流程

在这里插入图片描述

View的绘制流程是从ViewRoot的performTraversals方法开始的,经过measure、layout、draw三个过程才最终将一个View绘制出来

measure用来测量View的宽和高,完成后可通过getMessuredWidth / Height获取View测量后的宽 / 高

layout用来确定View在父容器中的位置,决定View的四个顶点的坐标和实际的View的宽和高,可通过对应的get方法获取

draw负责根据前面获得的View尺寸、位置将View绘制在屏幕上

measure过程

(1)performMeasure()会调用最外层ViewGroup的measure(),在其内调用onMeasure()。

(2)ViewGroup的onMeasure()中会调用measureChildren(),用于遍历子View然后循环调用 measureChild()

(3)measureChild()中会用先取出子元素的LayoutParams,再通过getChildMeasureSpec(),根据父容器的MeasureSpec + 当前View的LayoutParam + View的margin和padding值,创建当前View的MeasureSpec

(4)然后将MeasureSpec传递给当前View的子元素的measure(),在其内调用onMeasure()

(5)View的onMeasure()内会调用setMeasureDimension(getDefaultSize(),getDefaultSize()),getDefaultSize(),默认返回measureSpec的测量数值

(6)重复上述的循环调用直至当前View没有子元素,即可完成从顶级View到普通View的measure过程

layout过程

(1)performLayout()会调用最外层ViewGroup的layout(),大致流程如下

  • 通过setFrame()来设定View的四个顶点位置
  • 调用onLayout()确定子元素的位置

(2)onLayout()的实现逻辑与onMeasure类似,遍历子元素,循环调用setChildFrame() → 子元素的layout(),最终确定顶级View到普通View的位置

draw过程

(1)performLayout()会调用最外层ViewGroup的draw()方法,再经历如下的绘制流程

(2)绘制背景background.draw(canvas)

(3)绘制自己(onDraw)

(4)绘制子元素(dispatchDraw)

(5)绘制装饰(onDrawSrollBars)

(6)循环调用最终绘制出所有的View

View的测量宽高和最终宽高有什么区别?

在View的默认实现中,View的测量宽高和最终宽高是相等的,区别在于测量宽高形成于measure过程,而最终宽高形成于layout过程

以下两种情况可能会导致两者不相等:

(1)在layout中调用super.layout()对最终宽高做修改

(2)在某些情况下,View需要多次measure才能确定自己的测量宽高,在前几次的测量过程中,得出的结果可能和最终宽高不一致,但最终两者还是相同的

2.自定义View

(1)继承View重写onDraw():实现的效果不好通过布局方式实现,静态或动态显示一些不规则图形,如:Canvas绘制图形,需要自己支持wrap_content并处理padding

(2)继承ViewGroup派生特殊的Layout:实现自定义布局,需要合理地处理ViewGroup和其子元素的的测量、布局过程

(3)继承特定的View(如TextView):扩展已有View的功能,如自定义字体的TextView、带有删除按钮的EditText,不需要自己支持wrap_content并处理padding

(4)继承特定的Layout:扩展已有布局,不需要自己处理ViewGroup和其子元素的的测量、布局过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ConnorYan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值