一:SurfaceView基本使用
SurfaceView和View的资料很多,各种资料都会提到的比如什么安卓系统16ms刷新,耗时太久会造成视觉卡顿,view是主动刷新,SurfaceView适用于被动刷新,SurfaceView可以开启一个子线程在里面进行绘制操作,因此对于大量耗时操作的可以优先选用它,等等。此处不表。
SurfaceView的基本使用套路,有以下几个点:
1.自定义View类继承自SurfaceView对象,并实现SurfaceHolder.Callback接口,实现他的三个方法;
2.声明一个SurfaceHolder成员变量,并通过自定义SurfaceView的getHolder()方法获取SurfaceHolder对象,绑定到SurfaceHolder.Callback接口,实现对surface生命周期的监管;
3.开启一个子线程,进行界面的绘制。
4.自定义的SurfaceView就可用于xml布局,或者代码中,像普通view控件一样。
下例,是各种资料上常见的对SurfaceView应用的一个展示---绘图板。
主要内容:在构造函数中完成一些初始化操作,surface创建好之后即可开启绘制,绘制的本质也是使用Canvas进行画画,画圈,画图,画文字等等;其中,不同于自定义View在onDraw()方法中获取Canvas对象,自定义SurfaceView要通过surfaceHolder.lockCanvas()获取Canvas对象,之后利用画笔进行各种绘制,绘制完之后通过surfaceHolder.unlockCanvasAndPost(mCanvas);提交绘制。因为绘制都是在同一个Canvas之上,所以前面的绘制在后面不会被擦除,这时可以使用drawColor()方法来实现清屏的效果
public class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable { private SurfaceHolder surfaceHolder; private Canvas mCanvas; private boolean shouldDrawing=true; Paint mPaint; Path mPath; public MSurfaceView(Context context) { super(context); surfaceHolder=getHolder(); setKeepScreenOn(true); setFocusable(true); setFocusableInTouchMode(true); surfaceHolder.addCallback(this); mPaint=new Paint(); mPaint.setStrokeWidth(10); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPath=new Path(); } public MSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void surfaceCreated(SurfaceHolder holder) { shouldDrawing=true; new Thread(this).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } @Override public void run() { while(shouldDrawing){ draw(); } } private void draw(){ long start=System.currentTimeMillis(); try { mCanvas=surfaceHolder.lockCanvas(); mCanvas.drawColor(Color.RED); mCanvas.drawCircle(400,200,100,mPaint); mPaint.setTextSize(100); mCanvas.drawText(""+System.currentTimeMillis(),100,100,mPaint); float [] lines={0,500,0,1000,100,500,100,1000}; mCanvas.drawLines(lines,mPaint); mCanvas.drawPath(mPath,mPaint); }catch(Exception e){ }finally { if (mCanvas!=null) surfaceHolder.unlockCanvasAndPost(mCanvas); long end=System.currentTimeMillis(); if (end-start<100){ try { Thread.sleep(100-(end-start)); } catch (InterruptedException e) { e.printStackTrace(); } } } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: mPath.moveTo(event.getX(),event.getY()); break; case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(),event.getY()); break; case MotionEvent.ACTION_UP: mPath.reset(); break; } return true; } }
二、SurfaceView加MediaPlayer实现视频播放器
。。。待续