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中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出哈) 类似的 ...
随机推荐
- [IOI2007]训练路径
Description 马克(Mirko)和斯拉夫克(Slavko)正在为克罗地亚举办的每年一次的双人骑车马拉松赛而紧张训练.他们需要选择一条训练路径. 他们国家有N个城市和M条道路.每条道路连接两个 ...
- [Jsoi2011]分特产
Description JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望 ...
- 51 nod 1023 石子归并 V3(GarsiaWachs算法)
1023 石子归并 V3基准时间限制:2 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一 ...
- NOIP 2013
Prob.1 转圈游戏 找到循环节,然后快速幂.代码: #include<cstdio> #include<cstring> #include<iostream> ...
- 【bzoj4568 scoi2016】幸运数字
题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征. 一些旅行者希望 ...
- bzoj 2004: [Hnoi2010]Bus 公交线路
Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距 离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决 ...
- bzoj4767两双手 容斥+组合
4767: 两双手 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 684 Solved: 208[Submit][Status][Discuss] ...
- 【完整项目】使用Scrapy模拟HTTP POST,获取完美名字
1. 背景 最近有人委托我给小孩起个名字,说名字最好符合周易五行生克理论,然后给了我个网址,说像是这个网站中的八字测名,输入名字和生辰八字等信息,会给出来这个名字的分数和对未来人生的预测.当父母的自然 ...
- 数据结构之堆Heap
1. 概述 堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等. 2. 堆 ...
- 重构:从Promise到Async/Await
摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前 ...