android 学习笔记 view和surfaceView的2D绘图

    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博文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值