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的进阶使用.