View的onMeasure()、onLayout()、onDraw()总结

本文深入剖析Android自定义View的onMeasure()、onLayout()和onDraw()方法,详细解释了视图的测量、布局和绘制流程。从 DecorView 开始,讲解了如何通过 measure、layout 和 draw 确定View的尺寸、位置和绘制内容。onMeasure()中涉及MeasureSpec的模式,onLayout()用于确定子元素的位置,而onDraw()则负责实际的绘制操作。了解这些原理有助于高效实现自定义View。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义View是android开发中常有的一项工作,要想自定义View,你就必须熟练掌握View的测量、布局及绘制,了解其原理并会使用。

View视图绘制需要搞清楚两个问题,一个是从哪里开始绘制,一个是怎么绘制?

先说从哪里开始绘制的问题:我们平常在使用Activity的时候,都会调用setContentView来设置布局文件,没错,视图绘制就是从这个方法开始的;

再来说说怎么绘制的:

在我们的Activity中调用了setContentView之后,会转而执行PhoneWindow的setContentView,在这个方法里面会判断我们存放内容的ViewGroup(这个ViewGroup可以是DecorView也可以是DecorView的子View)是否存在。不存在的 话则会创建一个DecorView出来,并且会创建出相应的窗体风格,存在的话则会删除原先ViewGroup上面已有的View,接着会调用 LayoutInflater的inflate方法以pull解析的方式将当前布局文件中存在的View通过addView的方式添加到 ViewGroup上面来,接着在addView方法里面就会执行我们常见的invalidate方法了,这个方法不只是在View视图绘制的过程中经常 用到,其实动画的实现原理也是不断的调用这个方法来实现视图不断重绘的,执行这个方法的时候会调用他的父View的invalidateChild方法, 这个方法是属于ViewParent的,ViewGroup以及ViewRootImpl中都对他进行了实现,invalidateChild里 面主要做的事就是通过do while循环一层一层计算出当前View的四个点所对应的矩阵在ViewRoot中所对应的位置,那么有了这个矩阵的位置之后最终都会执行到 ViewRootImpl的invalidateChildInParent方法,执行这个方法的时候首先会检查当前线程是不是主线程,因为我们要开始准 备更新UI了,不是主线程的话是不允许更新UI的,接着就会执行scheduleTraversals方法了,这个方法会通过handler来执行 doTraversal方法,在这个方法里面就见到了我们平常所熟悉的View视图绘制的起点方法performTraversals了;

一、总体流程

视图的测量、布局、绘制都是按照视图树从上到下的,大致可分为DecorView-->ViewGroip-->View 这样三个层级

当Activity对象被创建完成,会将DecorView添加到Window中(显示),同时创建ViewRoot的实现对象ViewRootImpl与之关联。ViewRootImpl会调用performTraversals来进行View的绘制过程。经过measure,layout,draw三个流程才能完成一个View的绘制过程,分别是用于测量宽、高;确定在父容器中的位置;绘制在屏幕上三个过程。而measure方法会调用onMeasure函数,这其中又会调用子元素的measure函数,如此反复就能完成整个View树的遍历过程。其他两个流程也同样如此。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幽蓝丶流月

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

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

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

打赏作者

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

抵扣说明:

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

余额充值