surfaceView及view以及粒子动画介绍
1.粒子动画的开源实现
其实所有的游戏引擎都支持粒子效果,但是在标准的安卓UI中没有这个东西。也就是说如果你像创建一个具有粒子效果的app,你必须包含一个游戏引擎-高射炮打苍蝇,或者自己写一个。Leonids正好填补了这一空白。
2.View的动画实现原理
View要实现自定义动画,需要不断的执行onDraw()方法进行绘制,每次执行都对内部显示的图形做一些调整,我们假设 onDraw方法每秒执行20次,这样就会形成一个20帧的补间动画效果。但是现实情况是你无法简单的控制View.onDraw的执行帧数,因为onDraw方法是由系统帮我们调用的,我们是通过调用View的 invalidate方法通知系统需要重新绘制View,然后它就会调用View.onDraw方法。这些都是由系统帮我们实现的,所以我们很难精确去定 义View.onDraw的执行帧数
这个就是为什么我们这边要了解SurfaceView了,它能弥补View的一些不足。
3.SurfaceView相对于view的特色
SurfaceView可以控制动 画的帧数。在SurfaceView中内置一个LoopThread线程,这个线程的作用就是用来绘制图形,在SurfaceView中实例化一个 LoopThread实例,一般这个操作会放在SurfaceView
的构造方法中。然后通过在SurfaceView中的SurfaceHolder的 生命周期回调方法中插入一些操作,当Surface被创建时(SurfaceView显示在屏幕中时),开启LoopThread执行绘 制,LoopThread会一直刷新SurfaceView对象,当SurfaceView被隐藏时就停止改线程释放资源。
注意点:
1.因为SurfaceView允许自定义的线程操作Surface对象执行绘制方法,而你可能同时定义多个线程执行绘制,所以当你获取 SurfaceHolder中的Canvas对象时记得加同步操作,避免两个不同的线程同时操作同一个Canvas对象,当操作完成后记得调SurfaceHolder.unlockCanvasAndPost方法释放掉Canvas锁。
2.在调用doDraw执行绘制时,因为SurfaceView的特点,它会保留之前绘制的图形,所以你需要先清空掉上一次绘制时留下的图形。(View则不会,它默认在调用View.onDraw方法时就自动清空掉视图里的东西)。
3. 记得在回调方法:onSurfaceDestroyed方法里将后台执行绘制的LoopThread关闭,这里是使用join方法。这涉及到线程
如何关闭 的问题,多数人建议是通过一个标志位:isRunning来判断线程是否该停止运行,如果你想关闭线程只需要将
isRunning改成false即可,线 程会自动执行完run方法后退出。
4.surfaceView与view的区别
1. SurfaceView允许其他线程更新视图对象(执行绘制方法)而View不允许这么做,它只允许UI线程更新视图对象。
2. SurfaceView是放在其他最底层的视图层次中,所有其他视图层都在它上面,所以在它之上可以添加一些层,
而且它不能是透明的。
3. 它执行动画的效率比View高,而且你可以控制帧数。
4. 因为它的定义和使用比View复杂,占用的资源也比较多,除非使用View不能完成,再用SurfaceView否则最好
用View就可以。(贪吃蛇,俄罗斯方块,棋牌类这种帧数比较低的可以使用View做就好)
5.SurfaceView中的回调方法
自定义SurfaceView的基本流程:
1、继承SurfaceView
2、重写SurfaceView的至少一个构造方法
3、利用getHolder()方法得到SurfaceHolder的引用对象
4、给SurfaceHolder对象添加实现SurfaceHolder.Callback的接口对象
5、重写Callback的三个方法:surfaceChanged,surfaceCreated,surfaceDestroyed
6、利用SurfaceHolder对象设置Surface的格式
通过SurfaceHolder来管理Surface,实现SurfaceHolder.Callback.surfaceCreated和SurfaceHolder.Callback.surfaceDestroyed方法可以跟踪Surface被创建和销毁的事件。
6.出现的问题点
在关闭硬件加速的时候会出现其他控件后面有一大块的白色背景
在放到其他视图中使用自定义的surfaceview的时候一定要实现两个参数的构造器使用的时候尽量使用其他组视图进行包裹