首页 > 代码库 > SurfaceViewDemo
SurfaceViewDemo
SurfaceView是使用的双缓冲机制,所以在性能上面是比view更优越的类,在使用SurfaceView的时候其实并不是和SurfaceView直接打交道,而是通过SurfaceHolder的实例来控制SurfaceView的大小和格式等,并且主要用于监听surfaceview的状态,获取canvas对象的方式即通过surfaceholder的lockcanvas()方法锁定画布,并且返回一个canvas,然后就可以在获得的画布上面大展手脚了!!!当绘制完毕的时候通过surfaceholder的unloccanvasandpost();方法即可解锁画布,并且提交。
当对surfaceview进行监听的时候必须实现surfaceholder的callback接口即必须重写三个函数:surfacechanged、surfacecreated、surfacedestroyed最后通过surfaceholder类的addcallback(Callback callback);方法将其监听借口实例传入,即可完成对surfaceView的监听。以下是一个小的demo:
MSurfaceView.java
public class MSurfaceView extends SurfaceView implements Callback{ private Paint paint; private SurfaceHolder holder; private int x, y; private int radius; public MSurfaceView(Context context){ super(context); // TODO Auto-generated constructor stub paint = new Paint(); holder = this.getHolder(); holder.addCallback(this); paint.setColor(Color.RED); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub //mDraw(); } @Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub } public void mDraw(){ Canvas canvas = holder.lockCanvas(); canvas.drawText("HELLO SURFACEVIEW", x, y, paint); canvas.drawCircle(x, y, setRadius(), paint); holder.unlockCanvasAndPost(canvas); } private int setRadius(){ radius = (int)(Math.random()*20); return radius; } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub x = (int)event.getX(); y = (int)event.getY(); mDraw(); return true; } }
在Mainactivity.java文件里面将surfaceView作为当前显示的view:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(new MSurfaceView(this)); }}
运行效果如下:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
现在实现通过自定义一个线程来绘制surfaceview,线程的定义通过implements Runnable接口来完成,代码做如下修改:
public class MSurfaceView extends SurfaceView implements Callback, Runnable{ private Paint paint; private SurfaceHolder holder; private int x, y; private int radius; private Thread mThread; private boolean threadstate; public MSurfaceView(Context context){ super(context); // TODO Auto-generated constructor stub paint = new Paint(); holder = this.getHolder(); holder.addCallback(this); paint.setColor(Color.RED); setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub //mDraw(); } @Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub threadstate = true; mThread = new Thread(this); mThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub threadstate = false; } public void mDraw(){ Canvas canvas = holder.lockCanvas(); if (canvas != null) { canvas.drawRGB(0, 0, 0); canvas.drawText("HELLO SURFACEVIEW", x, y, paint); canvas.drawCircle(x, y, setRadius(), paint); } holder.unlockCanvasAndPost(canvas); } private int setRadius(){ radius = (int)(Math.random()*20); return radius; } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub x = (int)event.getX(); y = (int)event.getY();// mDraw(); return true; } @Override public void run() { int X = 500; // TODO Auto-generated method stub while(threadstate){ long start = System.currentTimeMillis(); mDraw(); long end = System.currentTimeMillis(); try { if ((end - start) < X) { Thread.sleep(X - (end - start)); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
其中的setradius()方法是简单的实现了为绘制的园随机取半径大小,MainAcitivity.java的代码没有改变。
运行效果如下: