Android画布和图形绘制---Canvas and Drawables(二)

长平狐 发布于 2012/10/16 10:20
阅读 572
收藏 0

注:本文译自:http://developer.android.com/guide/topics/graphics/2d-graphics.html

在View对象上绘图

如果应用程序不需要大量的图形处理或很高的帧速率(如一个棋类游戏、Snake游戏或另外的慢动画类应用程序),那么就应该考虑创建一个定制的View组件,并且用该组件的View.onDraw()方法的Canvas参数来进行图形绘制。这么做最大的方便是,Android框架会提供一个预定义的Canvas对象,该对象用来放置绘制图形的调用。

从继承View类(或其子类)开始,并定义onDraw()回调方法。系统会调用该方法来完成View对象自己的绘制请求。这也是通过Canvas对象来执行所有的图形绘制调用的地方,这个Canvas对象是由onDraw()回调方法传入的。

Android框架只在必要的时候才会调用onDraw()方法,每次请求应用程序准备完成图形绘制任务时,必须通过调用invalidate()方法让该View对象失效。这表明可以在该View对象上进行图形绘制处理了,然后Android系统会调用该View对象的onDraw()方(尽管不保证该回调方法会立即被调用)。

在定制的View组件的onDraw()方法内部,使用给定的Canvas对象来完成所有的图形绘制处理(如Canvas.draw…()方法或把该Canvas对象作为参数传递给其他类的draw()方法)。一旦onDraw()方法被执行完成,Android框架就会使用这个Canvas对象来绘制一个有系统处理的Bitmap对象。

注意:为了在一个线程中而不是主Activity的线程中发出一个失效请求,必须调用postInvalidate()。

有关继承View类的更多信息,请阅读创建定制化的组件(http://developer.android.com/guide/topics/ui/custom-components.html

示例程序,请看Snake游戏,它在SDK示例代码文件:/samples/Snake/。

在SurfaceView对象上绘图

SurfaceView对象是一个特殊的View类的子类,它在View层次树内提供了一个专用的图形绘制平面。这个图形绘制表面的主要目的是给应用程序提供一个辅助线程,以便应用程序不需要等待完成对系统的View层次树的绘制。相反,引用SurfaceView对象的辅助线程能够按照自己的节奏,把自己绘制在Canvas对象上。

首先需要创建一个继承SurfaceView类的子类。该子类还应该实现SurfaceHolder.Callback类,它是一个能够通知底层Surface类所发生的信息的接口。如Surface的创建、变化或销毁等。这些事件对于了解什么时候能够开始绘制图形、是否需要基于新的表面属性来进行调整、以及什么时候终止图形绘制和杀死某些任务,是至关重要的。在SurfaceView子类的内部也是定义辅助线程类的好地方,它会执行所有的把图形绘制到Canvas对象上的处理。

不要直接处理Surface对象,应该通过SurfaceHolder对象来处理它。因此,在SurfaceView子类被初始化的时候,要通过调用getHolder()方法来获得SurfaceHolder对象。然后应该通过调用addCallback()方法,来通知SurfaceHolder对象,它所能够接收SurfaceHolder回调对象(SurfaceHolder.Callback),然后再重写SurfaceView子类内部的每个SurfaceHolder.CallBacke方法。

为了能够在辅助线程内把图形绘制到Surface对象的Canvas对象上,必须把SurfaceHondler对象和用lockCanvas()方法获取的Canvas对象传递给辅助线程。现在就能够用给定的SurfaceHolder对象和Canvas对象开始图形绘制工作了,一旦用该Canvas对象完成了图形绘制任务,就要调用unlockCanvasAndPost()方法,把绘图用Canvas对象传递给该方法。现在Surface对象就会离开绘制图形的Canvas对象。每次想要重新绘制图形时,都要执行这个锁定和解锁的过程。

注意:每个通过SurfaceHolder对象获取的Canvas对象,它之前的状态都会被保留。为了正确的处理该图形,必须重新绘制整个Surface对象。例如,能够清除之前用drawColor()方法填充在Canvas对象中的颜色,或者是用drawBitmap()方法设置的背景图片。否则,就会看到之前被执行的图形绘制的轨迹。

示例应用程序,请看Lunar Lander游戏,它在SDK的示例文件夹:/samples/LunarLander/。


原文链接:http://blog.csdn.net/fireofstar/article/details/7643892
加载中
返回顶部
顶部