SurfaceView
一、简述
The SurfaceView
is a special subclass of View that
offers a dedicated drawing surface within the View hierarchy. The aim is to
offer this drawing surface to an application‘s secondary thread, so that the
application isn‘t required to wait until the system‘s View hierarchy is ready to
draw. Instead, a secondary thread that has reference to a SurfaceView can draw
to its own Canvas at its own pace.
二、使用步骤
准备工作:
1.定义一个类继承SurfaceView,并实现SurfaceHolder.CallBack接口。
2.通过SurfaceHolder来操作SurfaceView。这个holder可以通过在SurfaceView初始化时的getHolder()方法获得。
3.为SurfaceHolder添加回调接口实现类的对象。addCallBack()。
在SurfaceView的状态(当underlying surface is create ,changed ,or
destroyed)改变时,SurfaceHolder会通过CallBack的实现类的方法进行操作。
画图:
1.获得在次线程画画的Canvas。可通过surfaceHolder.lockCanvas()获得。(holder给予你这个画布)
2.在canvas上画画。可以调用canvas自带的一些画画方法
3.解除画布锁定并提交画布,这时候系统才真正实施画画。surfaceHolder.unlockCanvasAndPost(canvas)。
说明:a.每一次画画都是surfaceHolder.lockCanvas和unlockCanvasAndPost(canvas)成对出现。中间画画的内容是缓冲起来的,知道最后才提交画画。
b.每次画画都是在原先的canvas的基础上画画。不会自动清除canvas。适当时候,可以通过填充canvas颜色drawColor()或者设置背景图片drawBitmap()的方式clear
清除canvas内容(覆盖)
更多画画内容,参照http://developer.android.com/guide/topics/graphics/2d-graphics.html
下面是官方文档英文解释(中文部分是个人翻译的)
Class Overview
Provides a dedicated drawing surface embedded
inside of a view hierarchy. You can control the format of this surface and, if
you like, its size; the SurfaceView takes care of placing the surface at the
correct location on the screen
提供一个在view的层级下专注于画画的的surface(Handle
onto a raw buffer that is being managed by the screen compositor屏幕排版器所管理的”原生缓存“
的操作“句柄”)。你可以控制这个surface的格式,包括它的大小。SurfaceView负责将surface放在屏幕上正确的位置上。
The surface is Z ordered so that it is behind
the window holding its SurfaceView; the SurfaceView punches a hole in its window
to allow its surface to be displayed. The view hierarchy will take care of
correctly compositing with the Surface any siblings of the SurfaceView that
would normally appear on top of it. This can be used to place overlays such as
buttons on top of the Surface, though note however that it can have an impact on
performance since a full alpha-blended composite will be performed each time the
Surface changes.
这个surface在Z方向上有空间顺序(请详见数学三位坐标系),它位于hold它的SurfaceView的window后面。这个SurfaceView从hold住它的window中打了个洞,以至于它的surface内容得以显示。这个view的层级制将会负责正确的合成surface。任何SurfaceView的兄弟姐妹(组件)通常将会显示在它的上方。这个特性可以用来放置表面上层的覆盖层,例如Surface上面的button。值得注意的是,每一次这个Surface的改变都会执行alpha混合的合成操作。
The transparent region that makes the surface
visible is based on the layout positions in the view hierarchy. If the
post-layout transform properties are used to draw a sibling view on top of the
SurfaceView, the view may not be properly composited with the surface.
让这个surface可见的透明区域根据layout的层级位置而定。如果后面一层的变化属性被用来在改SurfaceView上方画一个兄弟view,这个view或许不会用这个surface来一起合理的合成。
Access to the underlying surface is provided
via the SurfaceHolder interface, which can be retrieved by calling getHolder()
.
对下层的surface的操作是通过SurfaceHolder的接口来实现的。SurfaceHolder可以通过getHolder()方法来得到。
The Surface will be created for you while the
SurfaceView‘s window is visible; you should implement surfaceCreated(SurfaceHolder)
andsurfaceDestroyed(SurfaceHolder)
to discover when the Surface is
created and destroyed as the window is shown and hidden.
当hold
该SurfaceView的window可见的时候,这个Surface将会被创建。你应该通过实现surfaceCreate(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)方法去发现,随着窗口显示和隐藏,这个Surface被create和destroyed。
One of the purposes of this class is to provide
a surface in which a secondary thread can render into the screen. If you are
going to use it this way, you need to be aware of some threading semantics:
这个SurfaceView类的一个目的是提供一个surface。通过这个surface,使用次要的线程去操作屏幕。如果你打算用这个方式使用它,你需要知道一些线程的语义。
- All SurfaceView and
SurfaceHolder.Callback
methods will be called from the
thread running the SurfaceView‘s window (typically the main thread of the
application). They thus need to correctly synchronize with any state that is
also touched by the drawing thread. - 所有的SurfaceView和SurfaceHolder.Callback方法将会被运行该Surfaceview‘的window的线程调用。
- You must ensure that the drawing thread only
touches the underlying Surface while it is valid -- betweenSurfaceHolder.Callback.surfaceCreated()
andSurfaceHolder.Callback.surfaceDestroyed()
. - 你必须保证drawing线程仅当下层的Surface有效时才接触那个surface,也即Surface在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()这两个方法间操作Surface.