draw(绘制)过程的作用是将View绘制到屏幕上面。View中有 draw() 方法和 onDraw() 方法,但onDraw()方法是空方法;ViewGroup中没有draw()方法,也没有onDraw()方法。由此可以推测出:ViewGroup的绘制过程调用的流程和View的绘制过程流程是相同的,且和onLayout()、onMeasure()方法一样,因为不同的ViewGroup子类有不同的绘制方式,因此将onDraw()方法下放到ViewGroup的子类中实现。接下来看一下View类的draw()方法的源码:

/**
* 在给定的Canvas画布上手动渲染这个View及其所有子元素;
* 在调用这个方法之前,这个View必须已经经过了layout布局过程;
* 在自定义View的时候,不能重写这个方法,而应该重写onDraw()方法。
*
* @param canvas View渲染的目标画布
*/
@CallSuper
public void draw(Canvas canvas) {
final int privateFlags = mPrivateFlags;
final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
/*
* 这种遍历绘制的方法需要执行几个步骤,且必须按适当的顺序执行
* 1. 绘制背景
* 2. (按需执行)保存画布层以应对褪色
* 3. 绘制View的内容
* 4. 绘制View中的子元素
* 5. (按需执行)绘制褪色边缘并恢复画布层
* 6. 绘制装饰物(前景、滚动条等)
*/
// Step 1、绘制背景
int saveCount;
if (!dirtyOpaque) {
drawBackground(canvas);
}
// 一般情况下,都会尽量跳过Step2和Stop5
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3、绘制View中的内容
if (!dirtyOpaque) onDraw(canvas);
// Step 4、绘制View中的子元素
dispatchDraw(canvas);
// Overlay是View内容的一部分,应该画在前景的底下(先于前景绘制)
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
// Step 6、绘制装饰物,如前景、滚动条
onDrawForeground(canvas);
// 完成绘制
return;
} /*
* 我们在下面做了完整的例程:
* 这是一种不常见的情况,在这种情况中渲染速度不是很重要,因此我们将上面的一些流程又重复了一遍
*/
// ......代码省略......
}

  从上面的代码可以看出,View的绘制过程总共分为六个步骤,但大多数情况下,第二步和第五步都会被省略,因此,我们在这里只分析1、3、4、6步骤。这样,View的绘制流程可以总结为: 绘制背景->绘制内容->绘制子元素->绘制其他(前景、滚动条等) ,对应的四个方法分别是: drawBackground() 、 onDraw() 、 dispatchDraw() 、 onDrawForeground() 。其中,onDraw()方法和dispatchDraw()方法在View类中没有实现,需要我们在自定义View中自行重写。

【Android - 自定义View】之View的draw过程解析的更多相关文章

  1. Android View框架总结(六)View布局流程之Draw过程

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52236145 View的Draw时序图 ViewRootImpl.p ...

  2. Android自定义View4——统计图View

    1.介绍 周末在逛慕课网的时候,看到了一张学习计划报告图,详细记录了自己一周的学习情况,天天都是0节课啊!正好在学习Android自定义View,于是就想着自己去写了一个,这里先给出一张慕课网的图,和 ...

  3. 自定义View Draw过程(4)

    目录 目录 1. 知识基础 具体请看我写的另外一篇文章:自定义View基础 - 最易懂的自定义View原理系列 2. draw过程作用 绘制View视图 3. draw过程详解 同measure.la ...

  4. 【Android - 自定义View】之View的工作过程简介

    View的工作过程分为三个过程: View的measure过程: View的layout过程: View的draw过程. 我们知道,一个Activity就是一个窗口,这个窗口中包含一个Window.一 ...

  5. android 自定义view详解

    1.自定义View前首先要了解一下View的方法,虽然有些不一定要实现. 分类 方法 描述 创建 Constructors View中有两种类型的构造方法,一种是在代码中构建View,另一种是填充布局 ...

  6. View学习(四)-View的绘制(draw)过程

    View的draw过程相比之于measrue过程,也是比较简单的.并且在我们自定义View时,也经常需要重写onDraw方法,来绘制出我们要实现的效果. 如之前的文章所说,绘制的流程也是起始于View ...

  7. Android应用程序窗体View的创建过程

    View类是android中非常重要的一个类.view是应用程序界面的直观体现,我们看到的应用程序界面就能够看作是View(视图)组成的. 那么我们应用程序的界面是怎么创建的呢,也就是应用程序的Vie ...

  8. Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)

    View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇  ...

  9. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

随机推荐

  1. Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required [ IDEA mybatis项目报错 ]

    今天笔者用Springboot框架整合Mybatis做一个小小的项目: 代码写完,在运行项目时,IDEA给我报了3处错误: org.springframework.beans.factory.Unsa ...

  2. 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework 之让代码更优雅

    [前言] 大家好,我是TANZAME.出乎意料的,我们在立冬的前一天又见面了,天气慢慢转凉,朋友们注意添衣保暖,愉快撸码.距离 TZM.XFramework 的首秀已数月有余,期间收到不少朋友的鼓励. ...

  3. 关于B/S模式CGI上传文件,遇到的问题归纳(待更新。。。)

    由于项目问题是基于web的,最近一直在改进web界面,由于产品需要升级,而且升级操作是由客户在web端完成,将软件包放在本地,由web上传到后台完成更新,之前做的是TFTP更新方式,但是需要借助第三方 ...

  4. (七)golang-变量之基本数据类型(看这篇就够了)

    1.整数类型 类型 有无符号 占用存储空间 表示范围 备注 int8 有 1字节 -2**7~2**7-1   int16 有 2字节 -2**15~2**15-1   int32 有 4字节 -2* ...

  5. C/c.pp:贪心,二分答案

    说是贪心有点牵强. 其次,答案满足单调性,如果在k次操作能完成那么在k+1次操作内也能完成. 因为大不了你就把多的一次对方操作再进行一次就好了. 怎么操作呢? 我们从头扫这个序列,遇到每一个不匹配位置 ...

  6. JavaScript中继承的实现方法--详解

    最近看<JavaScript王者归来>中关于实现继承的方法,做了一些小总结: JavaScript中要实现继承,其实就是实现三层含义:1.子类的实例可以共享父类的方法:2.子类可以覆盖父类 ...

  7. Zookeeper作为配置中心使用说明

    为了保证数据高可用,那么我们采用Zookeeper作为配置中心来保存数据.SpringCloud对Zookeeper的集成官方也有说明:spring_cloud_zookeeper 这里通过实践的方式 ...

  8. 使用Typescript重构axios(十四)——实现拦截器

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  9. 使用Typescript重构axios(二十八)——自定义序列化请求参数

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  10. canvas线条实践之运动的正方形

    原理说明: 1.通过rect实现正方形的绘制: 2.save保存canvas面板的保存,restore回复保存的canvas面板到初始状态: 3.translate用于改变canvas坐标的起始位置: ...