学习笔记-----Android的View绘制过程
边看源码边参考别人的博客等,做一下学习笔记。
要了解View的绘制,首先得知道View树的结构:(可以参考http://blog.csdn.net/qinjuning/article/details/7226787)

整个 View 树的绘图流程在ViewRoot.java类的performTraversals()函数展开,其绘制流程如下:

我们从最基本的思路来理解绘图流程:先确定所有View的大小,然后根据布局决定每个View的位置,然后开画!
这里着重关注具体绘图的Draw方法,其绘制流程为:

View.draw(Canvas) 方法:
/**
* Manually render this view (and all of its children) to the given Canvas.
* The view must have already done a full layout before this function is
* called. When implementing a view, implement
* {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
* If you do need to override this method, call the superclass version.
*
* @param canvas The Canvas to which the View is rendered.
*
* 根据给定的 Canvas 自动渲染 View(包括其所有子 View)。在调用该方法之前必须要完成 layout。当你自定义 view 的时候,
* 应该去是实现 onDraw(Canvas) 方法,而不是 draw(canvas) 方法。如果你确实需要复写该方法,请记得先调用父类的方法。
*/
public void draw(Canvas canvas) { / * Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background if need
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children (dispatchDraw)
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/ // Step 1, draw the background, if needed
if (!dirtyOpaque) {
drawBackground(canvas);
} // skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas); // Step 4, draw the children
dispatchDraw(canvas); // Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas); if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
} // we're done...
return;
} // Step 2, save the canvas' layers
... // Step 3, draw the content
if (!dirtyOpaque)
onDraw(canvas); // Step 4, draw the children
dispatchDraw(canvas); // Step 5, draw the fade effect and restore layers // Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas);
}
ViewGroup.dispatchDraw()方法:
dispatchDraw(Canvas canvas){
...
if ((flags & FLAG_RUN_ANIMATION) != 0 && canAnimate()) {//处理 ChildView 的动画
final boolean buildCache = !isHardwareAccelerated();
for (int i = 0; i < childrenCount; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {//只绘制 Visible 状态的布局,因此可以通过延时加载来提高效率
final LayoutParams params = child.getLayoutParams();
attachLayoutAnimationParameters(child, params, i, childrenCount);// 添加布局变化的动画
bindLayoutAnimation(child);//为 Child 绑定动画
if (cache) {
child.setDrawingCacheEnabled(true);
if (buildCache) {
child.buildDrawingCache(true);
}
}
}
}
final LayoutAnimationController controller = mLayoutAnimationController;
if (controller.willOverlap()) {
mGroupFlags |= FLAG_OPTIMIZE_INVALIDATE;
}
controller.start();// 启动 View 的动画
}
// 绘制 ChildView
for (int i = 0; i < childrenCount; i++) {
int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
final View child = (preorderedList == null)
? children[childIndex] : preorderedList.get(childIndex);
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
}
}
...
}
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
return child.draw(canvas, this, drawingTime);
}
/**
* This method is called by ViewGroup.drawChild() to have each child view draw itself.
* This draw() method is an implementation detail and is not intended to be overridden or
* to be called from anywhere else other than ViewGroup.drawChild().
*/
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
...
}
参考资料:
http://codekk.com/blogs/detail/54cfab086c4761e5001b253f
http://blog.csdn.net/qinjuning/article/details/7110211
http://blog.csdn.net/xyz_lmn/article/details/20385049
学习笔记-----Android的View绘制过程的更多相关文章
- Android View绘制过程
Android的View绘制是从根节点(Activity是DecorView)开始,他是一个自上而下的过程.View的绘制经历三个过程:Measure.Layout.Draw.基本流程如下图: per ...
- Android View 绘制过程
Android的View绘制是从根节点(Activity是DecorView)开始,他是一个自上而下的过程.View的绘制经历三个过程:Measure.Layout.Draw.基本流程如下图: per ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- Android中View绘制流程以及invalidate()等相关方法分析
[原文]http://blog.csdn.net/qinjuning 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简 ...
- Android中View绘制流程以及invalidate()等相关方法分析(转)
转自:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴 ...
- Android之View绘制流程源码分析
版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于稍有自定义View经验的安卓开发者来说,onMeasure,onLayout,onDraw这三个方法都不会陌生,起码多少都有所接触吧. 在安卓中 ...
- Mina框架的学习笔记——Android客户端的实现
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...
- android自定义View绘制天气温度曲线
原文:android自定义View绘制天气温度曲线 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012942410/article/detail ...
- Android学习笔记(第二篇)View中的五大布局
PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念 view是什么呢?我们已经知道一个Act ...
随机推荐
- openlayers
很久没有写东西了,最近突然想看看地图,就翻看了下,用了2-3周时间看看网页,学习做了下:先看做的效果:
- Lucene.net 多条件查询搜索
最近一直在研究lucene,目的是想让网站实现像搜索引擎那样的搜索,可以快速.准确的帮用户查询出想要的结果.废话不多说,上代码实例: 1.利用BooleanQuery进行多条件搜索(比较灵活) L ...
- Android自动化学习笔记:获取APK包名的几种方法
---------------------------------------------------------------------------------------------------- ...
- Jmeter plugin jp@gc - PerfMon Metrics Collector
Jmeter由于是开源工具,所以目前有很多插件可以供使用,最简单的方法是先把Plugin Manager安装了 下载地址:https://jmeter-plugins.org/wiki/Plugins ...
- cs端调用Ajax
private static string Descoder() { //ajax地址 string MealFilePath = "http://***/user/SetWebsite.a ...
- 服务器上搭建web环境
一.安装tomcat [root@localhost ~]# mkdir tomcat-src --新建文件夹 [root@localhost ~]# cd tomcat-src ...
- crontab 提示 command not found 解决方案
今天遇见一个问题,crontab的定时任务会报错:java command not found,但是手动执行脚本一直能成功. 猜想是环境变量的问题. 在crontab里添加个打印环境变量的任务: * ...
- android 非activity如何得到布局文件 (java文件中获取布局文件)
Android中得到布局文件对象有两种方式第一种,在Activity所在类中this.getLayoutInflater().inflater(R.layout.布局文件名,null);第二种,在非A ...
- Jquery day01
day01: 基础--选择器.属性和CSS.文档处理 day02: 高级--筛选.事件.效果.ajax jQuery介绍 JS类库 JavaScript 库封装了很多预定义的对象和实用函数.能帮助使用 ...
- FFT的分析以及matlab实验
FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换(DFT)的快速算法. 采样得到的数字信号,做FFT变换,N个采样点,经过FFT之后,就可以得到N个点 ...