canvas教程

Android4.2源码View.draw(Canvas canvas)中canvas分析

字号+ 作者:H5之家 来源:H5之家 2015-11-11 14:05 我要评论( )

ViewGroup java中绘制从dispatchDraw()开始,这里的Canvas由ViewRootImpl java中传入,此时Canvas是屏幕大小的画布。@Override protected void dispatchDraw(Can

> 移动开发 > Android > 正文 Android4.2源码View.draw(Canvas canvas)中canvas分析 2014-01-03         来源:u012604322的专栏      我要投稿

ViewGroup.java中绘制从dispatchDraw()开始,这里的Canvas由ViewRootImpl.java中传入,此时Canvas是屏幕大小的画布。

@Override protected void dispatchDraw(Canvas canvas) { ... more |= drawChild(canvas, child, drawingTime); }
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { return child.draw(canvas, this, drawingTime); }
drawChild函数只有一句话,指向了View.java的draw(Canvas canvas, ViewGroup parent, long drawingTime)函数。(这个函数不同于draw(Canvas canvas)函数,后者是View绘制过程开始的地方)

boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { ... int sx = 0; int sy = 0; if (!hasDisplayList) { computeScroll(); sx = mScrollX; sy = mScrollY; } final boolean hasNoCache = cache == null || hasDisplayList; final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE; int restoreTo = -1; if (!useDisplayListProperties || transformToApply != null) { restoreTo = canvas.save(); } if (offsetForScroll) { canvas.translate(mLeft - sx, mTop - sy); } else { if (!useDisplayListProperties) { canvas.translate(mLeft, mTop); } if (scalingRequired) { if (useDisplayListProperties) { // TODO: Might not need this if we put everything inside the DL restoreTo = canvas.save(); } // mAttachInfo cannot be null, otherwise scalingRequired == false final float scale = 1.0f / mAttachInfo.mApplicationScale; canvas.scale(scale, scale); } } ... if (!layerRendered) { if (!hasDisplayList) { // Fast path for layouts with no backgrounds if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { mPrivateFlags &= ~PFLAG_DIRTY_MASK; if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling dispatchDraw,this = " + this); } dispatchDraw(canvas); } else { if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling draw,this = " + this); } draw(canvas); } } else { mPrivateFlags &= ~PFLAG_DIRTY_MASK; ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags); ... }

上面这段代码,有两个需要指出的地方,一个就是canvas.translate()函数,这里表明了ViewRootImpl传进来的Canvas需要根据子视图本身的布局大小进行裁减,也就是说屏幕上所有子视图的canvas都只是一块裁减后的大小的canvas,当然这也就是为什么子视图的canvas的坐标原点不是从屏幕左上角开始,而是它自身大小的左上角开始的原因。

第二个需要指出的是如果ViewGroup的子视图仍然是ViewGroup,那么它会回调dispatchDraw(canvas)进行分法,如果子视图是View,那么就调用View的draw(canvas)函数进行绘制。



点击复制链接 与好友分享!回本站首页 上一篇:android开发之蓝牙主动配对连接手机 下一篇:android返回到上一个Activity 相关文章

Android4.0 中文版界面抢先看

android4.0源码下载 编译 系统体验~

android4.0 jni Hello World 开发

Android4.0中AppWidget的一些新玩意体

Android4.0.3源码分析——开机流程之Z

如何隐藏Android4.0及以上版本的Actio

android4.0下载问题

android4.0 statusbar加载icon

android4.0 中如何在app 中屏蔽HOME键

android4.0 Power、home、menu等按键

图文推荐

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5canvas核心技术图形、动画与游戏开发源码

    html5canvas核心技术图形、动画与游戏开发源码

    2017-05-02 17:42

  • SketchBook 2014 基础入门视频教程

    SketchBook 2014 基础入门视频教程

    2017-05-01 11:00

  • 21天学习android开发教程之SurfaceView与多线程的混搭

    21天学习android开发教程之SurfaceView与多线程的混搭

    2017-04-27 12:00

  • 在Android中需要通过graphics类来显示2D图形

    在Android中需要通过graphics类来显示2D图形

    2017-04-27 11:00

网友点评
"