请尊重分享成果,转载请注明出处:
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过程相关推荐

  1. Android 开源框架 ( 十六 ) 视频播放器 --- JiaoZiVideoPlayer(JieCaoVideoPlayer)

    原JieCaoVideoPlayer 不知道什么时候改名了,现在叫JiaoZiVideoPlayer. 项目GitHub地址:https://github.com/lipangit/JiaoZiVid ...

  2. android draw过程,android,view的执行过程onDraw、onSizeChanged,onFinishInflate

    小试view的执行过程,此是入门,高手绕道. ----------------------------------------------------------------------------- ...

  3. Android音频框架之二 用户录音启动流程源码走读

    前言 此篇是对<Android音频框架之一 详解audioPolicy流程及HAL驱动加载>的延续,此系列博文是记录在Android7.1系统即以后版本实现 内录音功能. 当用户使用 Au ...

  4. View的绘制流程-measure、layout、draw

    承接上文--Window.DecorView.ViewRootImp详解 我们打开一个Activity后,在ActivityThread中 的performLaunchActivity方法中,回调Ac ...

  5. 源码详解Android 9.0(P) 系统启动流程之SystemServer

    源码详解Android 9.0(P) 系统启动流程目录: 源码详解Android 9.0(P)系统启动流程之init进程(第一阶段) 源码详解Android 9.0(P)系统启动流程之init进程(第 ...

  6. Android面试收集录12 View测量、布局及绘制原理

    一.View绘制的流程框架 View的绘制是从上往下一层层迭代下来的.DecorView-->ViewGroup(--->ViewGroup)-->View ,按照这个流程从上往下, ...

  7. Android View框架的measure机制

    Android中View框架的工作机制中,主要有三个过程: 1.View树的测量(measure)Android View框架的measure机制 http://www.cnblogs.com/xyh ...

  8. Android开发-将自定义View布局到Layout中并调用

    写程序的时候,关于布局方面遇到并解决的问题 1.自定义View及其layout属性. 自定义View: [java] view plaincopy public class DrawView exte ...

  9. Android Animation学习(六) View Animation介绍

    Android Animation学习(六) View Animation介绍 View Animation View animation系统可以用来执行View上的Tween animation和F ...

  10. android版本更新框架、新闻客户端、音乐播放器、自定义View、Github客户端、指南针等源码...

    Android精选源码 XUpdate 一个轻量级.高可用性的Android版本更新框架 Android一个可定制的圆形进度条 Android自定义View分享 打钩动画源码 android音乐文件播 ...

最新文章

  1. python标准函数有哪些_python基本语法有哪些?
  2. 自媒体敏感词大全_让新媒体小编头疼的敏感词与错别字
  3. catia 工厂设计_SolidWorks、creo、UG哪个更适合机械设计?
  4. 一道经典的SQL面试题
  5. 强化学习-Vanilla Policy Gradient(VPG)
  6. Windows phone msdn 索引
  7. Spring IOC注解开发
  8. [西瓜书习题] 第二章 模型评估与选择
  9. 微课|中学生可以这样学Python(例8.25):二分法查找
  10. Mybatis批量删除Oracle语句,mybatis-oracle(ssi2)批量删除
  11. python利用Excel读取和存储测试数据完成接口自动化
  12. 如何使用基于范围的for()循环与std :: map?
  13. CentOS 5.6 使用光驱+系统光盘做YUM源
  14. 5.2自动扫描及装配数据
  15. 机器学习笔记 - 什么是高斯混合模型(GMM)?
  16. pta 7-5 输出2到n之间的全部素数 (15 分)
  17. 暴力解决个localhost跨域问题
  18. excel 删除重复项_在Excel 2007中删除重复项
  19. linux内核不能识别u盘分区,一种在Linux内核中识别特定USB大容量存储设备的方法及系统与流程...
  20. 关于根号p是无理数的另类证明

热门文章

  1. 使用Cmder替换cmd,让你的开发飞起来
  2. 设计模式(14)——原型模式(Prototype)
  3. 如何保存浮点型数值的图像? (Python的/ PIL)
  4. 算法笔记_面试题_8.零钱兑换
  5. 算法笔记_面试题_5.验证二叉搜索树
  6. java resultSet获取总行数
  7. 实用教程详解:用OpenCV的DNN模块部署YOLOv5目标检测
  8. 爬虫2 urllib用法
  9. C语言动态链表数据结构实现的学生信息项目
  10. 反作弊基本概念与机器学习的应用(1)