SurfaceView的使用
1.定义
SurfaceView继承自View,内嵌了一个专门用于绘制的Surface,Surfaceview不仅可以控制这个Surface的格式和尺寸,还能控制其绘制位置;因为可以直接从内存或者DMA等硬件接口取得图像数据,所以是个非常重要的绘图容器。
2.使用
首先要知道SurfaceView的一些特性,然后根据特性决定用途;
* SurfaceView 单位时间内完成界面的大量多次更新
* 双缓冲机制 :
* A线程----更新ui -----后台计算---更新ui
* B线程----后台计算----更新ui ---后台计算
* 可以在子线程更新ui
在主线程之外的线程中向屏幕绘图上,这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。
surfaceView.getHolder().addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { //surfaceView被销毁时调用 } @Override public void surfaceCreated(SurfaceHolder holder) { //surfaceView被创建时调用 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //surfaceView发生变化时调用 } });
首先继承SurfaceView并实现SurfaceHolder.Callback接口
使用接口的原因:因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。
3.实例
sv.getHolder().addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("surface被销毁了"); flag = false; } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("surface创建了"); flag = true; new Thread(){ public void run() { for(int i = 0;i<100;i++){ if(!flag){ return ; } //界面里面内容显示的控制器 SurfaceHolder holder = sv.getHolder(); Canvas canvas = holder.lockCanvas(); canvas.drawColor(Color.BLACK); int radius = 5+i; Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawCircle(250, 250, radius, paint); holder.unlockCanvasAndPost(canvas); SystemClock.sleep(100); } }; }.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("surface大小发生了变化"); } });
上述代码实现的内容是canvas动态地画一个半径逐渐增大的圆形成的动画;
整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---- >SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布----> Canvas绘画 ---->SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。
下面贴出SurfaceView实现视频播放器的实例:
sv = (SurfaceView) findViewById(R.id.sv); sp = getSharedPreferences("config", MODE_PRIVATE); sv.getHolder().addCallback(new Callback() { @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("surface被销毁"); if(mediaPlayer!=null){ int position = mediaPlayer.getCurrentPosition(); Editor editor = sp.edit(); editor.putInt("position", position); editor.commit(); mediaPlayer.stop(); mediaPlayer.release(); } } @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("surface被创建"); try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource("/mnt/sdcard/oppo.3gp"); mediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); } //指定多媒体的内容实在holder里面显示 mediaPlayer.setDisplay(holder); mediaPlayer.start(); mediaPlayer.seekTo(sp.getInt("position", 0)); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } });
4.小结
SurfaceView的使用远不止于此,它比想象的更加强大,后面会涉及到SurfaceView的进阶使用.