为了更好的学习和理解Canvas和Drawable,翻译了谷歌官方API指南的文章。自:http://developer.android.com/intl/zh-cn/guide/topics/graphics/2d-graphics.html 有错误欢迎指出。不过,该文章只能算是一个引导,还是没有更深入的详细写出Canvas、Paint、Bitmap和Xfermode等对象之间的关系。计划在进一步研究一下API和应用之后,再写一篇总结。
安卓API指南——Canvas和Drawable
正文:
安卓framework的API提供了一系列供2D绘图的API,允许用户在Canvas画布上渲染自定义的图画,或是修改已有的View来自定义它们的外观。在2D绘图时,通常有以下两种方法:
1. 在用户布局中的一个View对象上绘制图像或动画。这种方式是由系统的常规View层绘图程序完成的,用户只需简单定义图像即可。
2. 直接在Canvas上绘图。该方式需要用户调用相应类的onDraw方法(在其中传入用户的Canvas),或是调用Canvas的drawXXX()方法(如drawPicture())。这种方法同样可以绘制任意的动画。
如果用户只需要绘制一些简单的图形,该图形既不需要需要动态改变,也不是那种注重图像表现的游戏应用的话,方法1(即向View上画图)是最好的选择。比如,用户希望表现另一静态应用中的静态图片或提前定义好的动画,就可以把它们绘制在View上。
更多信息请参阅Drawable类。
在画布上画图,则是在应用需要经常重绘自己时最好的方法。比如游戏就应该采用画布绘图。有两种方法能够实现这种画图:
1. 用户在布局中自定义View控件时,可以在和UI Activity同一个线程中,调用invalidate()方法,随后处理回调onDraw()方法。
2. 在处理SurfaceView的子线程中,倾线程最大的速度在Canvas上绘图。(无需invalidate方法)
使用Canvas绘图
当用户编写一款需要专门细致绘图或控制动画的应用时,应该采用Canvas绘图的方式。Canvas此时作用类似内存或接口,承载了用户所有的绘图回调方法,然后加入到图片该绘制的区域中。通过Canvas图片实际上会在底层的一张窗体中的Bitmap上绘制。
在onDraw回调方法中绘图时,Canvas是提供好的,用户只需在其上调用绘图方法即可。
如果是处理一个SurfaceView对象,也可以从SurfaceHolder.lockCanvas()方法中返回一张Canvas。(这两种情况都会在下文中论述)
不过如果要创建一个新的Vancas,则必须定义绘图实际发生的Bitmap。也就是说,Canvas永远都需要一个Bitmap。用户可以通过以下方式声明一个新的Canvas。
Bitmap b =Bitmap.createBitmap(100,100,Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
如此用户的Canvas就会在定义的Bitmap上被绘制。在该Canvas绘制完毕后,用户还可以通过Canvas.drawBitmap(Bitmap,…)相关的方法把
这张Bitmap传给另一个Canvas。推荐大家使用View.onDraw方法或是SurfaceHolder.lockCanvas提供的Canvas来完成最终的绘图(见下文)。
Canvas类拥有自己的一套绘图方法供用户使用,如drawBitmap、drawRect、drawText等等等等。其他有的类也有draw方法。比如用户可能需要在Canvas上添加一些Drawable对象。Drawable就有自己的draw方法,此时Canvas可作为它的参数被传入。
On a View 在View上绘图
如果应用并不需要大量的处理或多高的帧速(比如象棋、贪吃蛇或其他慢动画应用),就可以考虑建立自定义View控件,并在View的onDraw()方法中用Canvas绘图。这时最爽的地方就是Android framework会提供给用户一个预先定义好的Canvas,来让用户调用绘图方法。
先继承View类(或它相关的子类)随后定义onDraw()方法。该方法会在需要View绘制自身时,被Androidframework调用。此时就可以通过该方法传入的Canvas来调用所有用户需要的绘图方法。
Android framework只会在必要时调用onDraw。当应用准备好被绘制时,必须通过invalidate()