【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 ...
随机推荐
- 大觅网05Day
1.Mycat概述 在此前的服务器对数据库的存储数量要求并不高的时候,被经常使用的MySql数据基本能够满足对数据存储的要求. 但随着技术的不断发展,MySql甚至Redis都无法满足现今存储数量的指 ...
- NOIP模拟 8
T1 水题,可是没A,惭愧. 值得一提的是,虽然我忘了kmp,现场制造的kmp因为缺少针对题目的特判挂了,但是现场制造的kmp板子能过字符串板子题.. 对..把板子改装了...而且改对了! nx[]= ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(3) - 使用Conductor切换页面
前两章中, 我们已经实现了这个图书管理系统的登录窗口, 并实施了完善的单元测试. 该是时候回过头来关注我们的主窗口了. 一个功能丰富的系统一般会有多个页面, 我们图书管理系统虽然是"简易&q ...
- Java高性能反射工具包ReflectASM
ReflectASM 使用字节码生成的方式实现了更为高效的反射机制.执行时会生成一个存取类来 set/get 字段,访问方法或创建实例.一看到 ASM 就能领悟到 ReflectASM 会用字节码生成 ...
- 『题解』Codeforces446C DZY Loves Fibonacci Numbers
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description In mathematical terms, the sequence \( ...
- inline-block元素间隙产生及去除方法
当我们把元素属性display设置成inline-block时,元素之间就会产生间隙 <!DOCTYPE html><html> <head> <meta c ...
- html5 textarea 写入换行的方法
html5 textarea 写入换行的方法<pre> <textarea id="fwe" class="selmiao" cols=&qu ...
- php微信卡券logo上传方法
php微信卡券logo上传方法 <pre> $xiangmupath = $this->getxiangmupath(); $logo = $xiangmupath . '/imag ...
- maven打包记录1
在需要打包的项目目录下找到pom.xml文件 (过程中可能遇到 :-Dmaven.multiModuleProjectDirectory system property is not set. Che ...
- Laravel生命周期与原理
一旦用户(浏览器)发送了一个HTTP请求,我们的apache或者nginx一般都转到index.php,因此,之后的一系列步骤都是从index.php开始的,我们先来看一看这个文件代码. <?p ...