【Android - 自定义View】之View的draw过程解析
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过程解析的更多相关文章
- Android View框架总结(六)View布局流程之Draw过程
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52236145 View的Draw时序图 ViewRootImpl.p ...
- Android自定义View4——统计图View
1.介绍 周末在逛慕课网的时候,看到了一张学习计划报告图,详细记录了自己一周的学习情况,天天都是0节课啊!正好在学习Android自定义View,于是就想着自己去写了一个,这里先给出一张慕课网的图,和 ...
- 自定义View Draw过程(4)
目录 目录 1. 知识基础 具体请看我写的另外一篇文章:自定义View基础 - 最易懂的自定义View原理系列 2. draw过程作用 绘制View视图 3. draw过程详解 同measure.la ...
- 【Android - 自定义View】之View的工作过程简介
View的工作过程分为三个过程: View的measure过程: View的layout过程: View的draw过程. 我们知道,一个Activity就是一个窗口,这个窗口中包含一个Window.一 ...
- android 自定义view详解
1.自定义View前首先要了解一下View的方法,虽然有些不一定要实现. 分类 方法 描述 创建 Constructors View中有两种类型的构造方法,一种是在代码中构建View,另一种是填充布局 ...
- View学习(四)-View的绘制(draw)过程
View的draw过程相比之于measrue过程,也是比较简单的.并且在我们自定义View时,也经常需要重写onDraw方法,来绘制出我们要实现的效果. 如之前的文章所说,绘制的流程也是起始于View ...
- Android应用程序窗体View的创建过程
View类是android中非常重要的一个类.view是应用程序界面的直观体现,我们看到的应用程序界面就能够看作是View(视图)组成的. 那么我们应用程序的界面是怎么创建的呢,也就是应用程序的Vie ...
- Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)
View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇 ...
- Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...
随机推荐
- Linux系统运行级别和关机重启命令介绍
Linux系统运行级别介绍 Linux系统有七种运行级别(Run Level),各个运行级别下,系统有不同的状态,各个级别的意义描述如下. 0:关键级别1:单用户运行级别,运行rc.sysinit和r ...
- Mui 长按保存图片
必须先要 引入 mui.js,然后参考具体代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...
- Java内存模型相关原则详解
在<Java内存模型(JMM)详解>一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则.而Java内存模型又是围绕着在并发过程中如何处理原子性.可见性以及有序性这三个特征来构 ...
- Topshelf+Quartz在.Net Core框架下的实现
在我们日常开发工作中,经常会运用到Quartz+Topshelf组件的组合来开发一些定时任务.那么在.Net Core下如何去使用呢?我自己尝试搭建了一个测试项目,过程中遇到了以下一些问题: Quar ...
- vue学习笔记(一)入门
前言 随着前端不断的壮大,许多公司对于前端开发者的需求也越来越多了,作为一名优秀的前端工程师,如果连vue和react都不会的话,那真是out了,为什么那么说呢?这是我在招聘网站上截的一张图,十家公司 ...
- ABAP中时间戳的处理
UTC(UTC, Universal Time Coordinated,通用协调时)时间戳,分为长时间戳和段时间戳,其中长时间戳餐开始的系统的数据元素TIMESTAMPL,类型为DEC(21,7):而 ...
- 不用循环控制、条件控制、三目运算符 实现阶乘n!
long func(int n) { ( n <= 1 && (n=1) ) || ( n*=func(n-1)); return n; } template<int N& ...
- Markdown 编辑图片居中
Markdown 编辑图片居中 <center><p></p& ...
- Go调用cpp类
CGO是C语言和Go语言之间的桥梁,所以GO是没有办法直接使用CPP的类的. 我们可以通过增加一族C语言函数接口作为CPP类和CGO之前的桥梁的,这样 就可以实现C和Go之间的互联. my_buffe ...
- 虚拟机操作系统内设置固定IP以及克隆虚拟机
以下为我自己整理的克隆虚拟机和设置固定IP的方法,记录一下,以防忘记: 桥接模式网络配置 1.配置ip地址等信息在/etc/sysconfig/network-scripts/ifcfg-ens33文 ...