Android View框架总结(六)View布局流程之Draw过程
请尊重分享成果,转载请注明出处:
http://blog.csdn.net/hejjunlin/article/details/52236145
- View的Draw时序图
- ViewRootImpl.performTraversals过程
- ViewRootImpl.performDraw过程
- View.draw方法
- View.dispatchDraw过程
- LinearLayout的onDraw过程
View的Draw时序图
前面几篇通过对View树的measure和layout过程分析事,接下来将结合前两步得到的测量值及在视图中的位位置,开始进行绘制操作,一步比一步复杂,draw过程比前面都要复杂,draw的不好,就会出现overdraw。下面请仔细看分析过程:
draw的原始触发点还是在ViewRootImpl的performTraversals(执行遍历)方法中,开始分析流程:可以结合我画的时序图一起看,方便理解。
ViewRootImpl.performTraversals()
ViewRootImpl.performDraw()
ViewRootImpl.draw()
measure和layout过程直接调用的是ViewRootImpl的performMeasure和performLayout方法,draw调用的是ViewRootImpl的performDraw()方法,再由performDraw中的draw(boolean fullRedrawNeeded)方法来调用ViewTreeObserver中的dispatchOnDraw()方法,进行通知所有挂在view树上的view开始draw。
ViewTreeObserver.dispatchOnDraw()
View.onDraw()
对于View.java和ViewGroup.java,onDraw()默认都是空实现,因为具体View本身是什么,这就是做框架,提供空间,你要在里面自定义什么view是使用者所决定,但是可以提供默认方法。
View.draw()
View的另一个draw方法
View.drawBackground() — // Step 1, draw the background
View.onDraw() — // Step 3, draw the content
View.dispatchDraw() — // Step 4, draw the children
View.onDrawScrollBars — // Step 6, draw decorations (foreground, scrollbars)
View中dispatchDraw()默认为空实现,因为其不包含子view,而ViewGroup重写了dispatchDraw()来对其子view进行绘制,一般自定义view不应该对dispatchDraw()进行重载,因为它已经体现了View系统绘制的流程。那么,接下来我们继续分析下ViewGroup中dispatchDraw()的具体流程:
ViewGroup.dispatchDraw()
ViewGroup.drawChild()
- dispatchDraw()的关键就是通过for循环调用drawChild()对ViewGroup的每个子视图进行绘制,上述代码中如果FLAG_USE_CHILD_DRAWING_ORDER为true,则子视图的绘制顺序通过getChildDrawingOrder来决定,默认的绘制顺序即是子视图加入ViewGroup的顺序,而我们可以重载getChildDrawingOrder方法来更改默认的绘制顺序,让子view重叠在父view上,或者说是挂在父view上。
- drawChild()的核心就是为子视图分配合适的canvas画布区,画布区的size是d在layout过程决定的,而画布区的位置取决于滚动值以及子视图当前的动画。设置画布区后就会调用childview的draw()函数,如果childview的包含SKIP_DRAW标识,仅调用dispatchDraw(),即跳过子视图本身的绘制,但要绘制视图可能包含的childview。
ViewGroup.drawChild()
Draw过程小总结:
- 自定义View是一个ViewGroup,则需要递归绘制包含的所有子View。
- View默认不会绘制任何内容,真正的绘制都需要自己在子类中实现,只是做好绘制流程,这就是框架的职责。
- 区分View动画和ViewGroup布局动画,前者指的是View自身的动画,可以通过setAnimation添加,后者是专门针对ViewGroup显示内部子视图时设置的动画,可以在xml布局文件中对ViewGroup设置layoutAnimation属性(譬如对LinearLayout设置子View在显示时出现逐行、随机、下等显示等不同动画效果)。
- 在获取画布剪切区(每个View的draw中传入的Canvas)时会自动处理掉padding,子View获取Canvas不用关注这些逻辑,只用关心如何绘制即可。
- 默认情况下子View的ViewGroup.drawChild绘制顺序和子View被添加的顺序一致,但是你也可以重载ViewGroup.getChildDrawingOrder()方法提供不同顺序。
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android View框架总结(六)View布局流程之Draw过程的更多相关文章
- Android View框架总结(四)View布局流程之Measure
View树的measure流程 View的measures时序图 View布局流程之measure measure过程 View的measure过程 ViewGroup的measure过程 Frame ...
- Android View框架总结(五)View布局流程之Layout
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52216195 View树的Layout流程 View的Layout时序图 View布局 ...
- Android显示框架:自定义View实践之绘制篇
文章目录 一 View 二 Paint 2.1 颜色处理 2.2 文字处理 2.3 特殊处理 三 Canvas 3.1 界面绘制 3.2 范围裁切 3.3 集合变换 四 Path 4.1 添加图形 4 ...
- Android的学习第六章(布局一LinearLayout)
今天我们来说一下Android五大布局-LinearLayout布局(线性布局) 含义:线性布局,顾名思义,指的是整个Android布局中的控件摆放方式是以线性的方式摆放的, 主要作用:主要对整个界面 ...
- Android的学习第六章(布局一TableLayout)
今天我们来简单的说一下Android不居中的TableLayout布局(表格布局) 表格布局的意思就是将我们的布局看做为一个表格,主要用于对控件进行整齐排列 我们看一个简单的案例 <TableL ...
- Android的学习第六章(布局二--RelativeLayout)
今天我们来说一下Android布局中的Relativelayout布局(相对布局) 根据英译过来意思是相对布局,很容易理解,这一样布局使用的是元素与元素之间的微调做到布局的 含义:通过元素与元素之间的 ...
- Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)
View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇 ...
- Android View框架的draw机制
概述 Android中View框架的工作机制中,主要有三个过程: 1.View树的测量(measure) Android View框架的measure机制 2.View树的布局(layout)Andr ...
- Android 自定义View修炼-Android中常见的热门标签的流式布局的实现
一.概述:在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出哈) 类似的 ...
随机推荐
- 【数据结构】【平衡树】无旋转treap
最近在研究平衡树,看起来这种东西又丧水又很深,感觉很难搞清楚.在Ditoly学长的建议下,我先学习了正常的treap,个人感觉这应该是平衡树当中比较好懂的而且比较好写的一种. 然而,发现带旋treap ...
- ●杜教筛入门(BZOJ 3944 Sum)
入门杜教筛啦. http://blog.csdn.net/skywalkert/article/details/50500009(好文!) 可以在$O(N^{\frac{2}{3}})或O(N^{\f ...
- [LSGDOJ1822]书架 Splay
题目描述 Sally有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. Sally在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一 ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- [Noi2016]国王饮水记
来自FallDream的博客,未经允许,请勿转载,谢谢. 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳蚤实在太多,跳蚤国王 ...
- SpringMVC 环境搭建(HelloWorld)
SpringMVC 入门案例 环境 * springMVC * web 构建文件目录结构 修改dispatcher-servlet.xml文件 修改web.xml
- 第二周个人作业WordCount
1.Github地址 https://github.com/JingzheWu/WordCount 2.PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...
- linux安装mysql数据库
安装mysql 1.下载MySQL的安装文件 安装MySQL需要下面两个文件: MySQL-server-4.0.23-0.i386.rpm MySQL-client-4.0.23-0.i386.rp ...
- js改变dom对象样式
object.style.display = value; objcet对象必须是确定单个对象. 若以class名和标签名查找,需要指定对象集合中的第几个.
- C# 制作屏保(图片位置随机变化)
最近无所事事,闲着无聊,在网上翻看资料时碰巧看到了屏保制作,根据大神的思路也理解到屏保也不是很难.因此根据我自己的理解,动手谢了一个屏保. 首先,打开VS2010创建一个Windows窗体应用程序,名 ...