学习笔记-----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 ...
随机推荐
- OpenGL学习笔记4——模型视图变换
以日月地为例的一个模型视图变换.绕了比较多的弯路,下面是几个注意点总结. 注意点: 1.GL函数对模型的操作是基于当前局部坐标系,即模型坐标系而非世界坐标系,二者只在第一次初始化完毕之后才重合: 2. ...
- 这些年正Android - 身在他乡
“从不敢想到想去做到,做到我想的,事实证明我并不像他们想象的那样脆弱.我只是需要一盏灯,一架钢琴,一支麦克风.曾经想象过做一名医生救死扶伤,也曾想过做律师,做记者,做奥运冠军,但是都没有结果.因为我最 ...
- Excel 执行Sql 将查询结果输出到EXCEL指定位置
Dim cnn,strSql Set cnn = CreateObject("adodb.connection") cnn.Open "driver={sql serve ...
- EL表达式显示数据取整问题
第一 插入fmt标签库 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%&g ...
- Dev ChartControl鼠标移动显示坐标点
his.chartIRC_RATES.MouseMove += new MouseEventHandler(chartIRC_RATES_MouseMove); ToolTipController t ...
- awk 命令
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...
- 学习计划-----java初级工程师
目标: 1.具备扎实的JAVA基础,对数据结构.基本算法熟练掌握,并具备基本的算法设计能力. 2.前台:精通JSP/Servlet.HTML.JavaScript.Ajax.Jquery, XML.J ...
- ---bind 配置
http://blog.csdn.net/zjunjun/article/details/7419125
- WPF打印、预览、导出PDF
本人很懒,已找到可使用样例 例: http://www.cnblogs.com/guogangj/archive/2013/02/27/2934733.html
- 现在开始(Do It Now)
现在开始(Do It Now) 很多年前读大学的时候,我决定制定一个计划挑战自己:只用三个学期完成其他人通常花费四年的课程,能否毕业.这篇文章(此文为翻译)详细的说明了我在成功实现该目标过程中的所有时 ...