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中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出哈) 类似的 ...
随机推荐
- 洛谷P1397 [NOI2013]矩阵游戏
矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...
- hdu 5869 区间不同GCD个数(树状数组)
Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K ( ...
- hihocoder——1041国庆出游(搜索)
描述 小Hi和小Ho准备国庆期间去A国旅游.A国的城际交通比较有特色:它共有n座城市(编号1-n):城市之间恰好有n-1条公路相连,形成一个树形公路网.小Hi计划从A国首都(1号城市)出发,自驾遍历所 ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- 【Toll!Revisited(uva 10537)】
题目来源:蓝皮书P331 ·这道题使得我们更加深刻的去理解Dijkstra! 在做惯了if(dis[u]+w<dis[v])的普通最短路后,这道选择路径方案不是简单的比大小的题横在了 ...
- 例10-11 uva11181
题意:n个人去逛超市,第i个人买东西的概率是pi,,计算每个人实际买了东西的概率 思路: 搜索标处理所以的情况,得出所有概率和all(开始天真的以为是1 - -,就说怎么案例看着怪怪的),用tt[i] ...
- 四个常用的 Rewrite 使用范例
一.防盗链功能只这四行就实现了防盗链,原理是利用REFERER判断网页来源,缺点是REFERER容易伪造. RewriteEngine On RewriteCond %{HTTP_REFERER} ! ...
- Windows 2008 R2_NLB网络负载均衡(图文详解)(转)
目录 前言 软件环境 DNS域名服务器 DNS服务器原理 DNS域名空间 DNS区域 DNS服务器的类别 DNS查询模式 缓存文件 配置DNS服务器 DNS服务的应用 新建子域 在DNS正向解析中新建 ...
- 关于thymeleaf th:replace th:include th:insert 的区别
关于thymeleaf th:replace th:include th:insert 的区别 th:insert :保留自己的主标签,保留th:fragment的主标签. th:re ...
- 解决 Popup 位置不随窗口移动更新的问题
Popup弹出后,因业务需求设置了StaysOpen=true后,移动窗口位置或者改变窗口大小,Popup的位置不会更新. 如何更新位置? 获取当前Popup的Target绑定UserControl所 ...