android中的绘图可以有两类,2D绘图和3D绘图。2D绘图中,经过理解和分析,个人觉得分为:1.简单的资源放置型;2.通过画布canvas绘图。
1.简单的资源放置型;
此类绘图可以简单的理解为向系统放置资源,让系统显示,即在android已经提供的资源中设置图像,应用提供的画图接口对图像做一些简单的修饰。例如要在主视图中显示画面,可以通过main.xml添加组件imageview,然后设置imageview的属性即可。该方法操作简单,但是没有实时交互功能,只能满足最基本的绘图需求,即显示图片之类的。
2.通过画布canvas绘图;
此种方法又可以分为在view上绘图和在surfaceview绘图,只需要在activity中通过setcontentview()来设置选择的view类型即可。
既然是通过canvas绘图,那么canvas从何而来显得很重要。view类通过重写onDraw(Canvas canvas)函数来完成绘图操作,此时参数canvas就是绘图用到的画布,也是该view关联的画布。用户只需要在onDraw()中实现要绘制的图形内容,当视图发生改变时,系统便会自动调用ondraw()函数了,而surfaceView不会自动调用onDraw()函数。
那么系统怎么知道视图发生改变了呢?在程序启动时,生成view时系统会自动调用ondraw()函数,具体的调用机制没有分析,在生成视图后,用户可以通过方法invalidate()给系统发送视图改变的信息。当然如果不在UI主线程中,则需要通过postInvalidate()发送信息(关于UI主线程和子线程的绘图问题以后再谈。现在是一知半解的)。
通过分析view的绘图实现可以看出,onDraw()是一种系统响应机制,是android自己调用onDraw()的。用户需要通知系统我要重新绘图。这样对于实时性非常高需要快速反应的绘图就不适合。
surfaceview作为专职绘图的view,它提供了接口SurfaceHolder.Callback的实现,通过SurfaceHolder.Callback的三个函数
surfaceChanged(SurfaceHolder holder, int format, int width,int height)、
surfaceCreated(SurfaceHolder holder)、
surfaceDestroyedSurfaceHolder holder)
来触发绘图操作。
用户可以在surfaceChanged(...)、surfaceCreated(...)中写入绘图内容,此时和view的绘画机制相差无几,那么surfaceview和view的主要区别如何体现呢?surfaceview与view相比,它能生成单独的子线程,从而将绘图操作从surfaceview中剥离出来,或者添加一道数据处理管卡。这一过程的实现主要是由SurfaceHolder实现的。前面说过找到需要绘制的canvas最重要,只要有canvas在手,管他是view还是surface,我们就能绘图了。所以单独生成子线程要能在子线程中得到surfaceview关联的canvas。surfaceholder则帮助实现了这一功能,具体实现看下面代码:
SurfaceHolder surfaceHolder = getHolder() ; //取得holder,这个holder主要是对surface操作的适配,用户不具备对surface操作的权限
surfaceHolder.addCallback(this) ; //注册实现好的callback
Canvas canvas = surfaceHolder.lockCanvas() ; //取得画图的Canvas
/*---------------------------------画图
**-------------------------------- 画图结束*/
surfaceHolder.unlockCanvasAndPost() ; //提交并显示
要绘制canvas需要做四个基本操作,即获取holder,注册callback,取得canvas画布,提交并显示canvas类容。上述四个操作不一定要写在一个函数中,注册callback可以分开写,如构造函数中,此时写成getHolder().addCallBack()即可。这四个操作中,获取canvas画布的操作是关键,通过surfaceHolder.lockCanvas()就能得到canvas画布,所以向子线程传送获得的canvas就能实现画图操作的分离。在子线程中,用户可以自行绘制图形,也可调用onDraw()函数(该函数在surfaceview中是不能自动调用的) 。这样就能提高绘图的实时性,并在保证良好响应的情况下提高数据的处理能力。
关于绘图更详细的类容可参见http://hi.csdn.net/link.php?url=http://blog.csdn.net%2Fyili_xie中的一篇Android Graphic : apk and Skia/OpenGL|ES的博文