【Android 笔记】SurfaceView 的使用
SurfaceView 也是 View 的一种,但它可以在非 UI 线程显示、更新等。所以可以用它来完成一些绘制复杂、更新频繁的 UI(如游戏)。
######区别于 View 的特点
- View 使用与主动更新,SurfaceView 使用于被动更新
- View 运行与 UI 线程,SurfaceView 运行于子线程
- SurfaceView 运用了双缓冲机制
Demo
完成一个使用 SurfaceView 的绘图板。
步骤
1)继承 SurfaceView,实现 SurfaceViewHolder.Callback 和 Runnable:Callback.surfaceCreated() 开启线程;Runnable.run() 中调用绘制方法
2)初始化成员变量:SurfaceHolder、Canvas、boolean(线程标志位)
3)编写绘制逻辑:绘制前 lockCanvas,绘制完成 unlockCanvasAndPost
代码:
public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback, Runnable{
private SurfaceHolder mHolder;
private Canvas mCanvas;
private Paint mPaint;
private boolean isDraw; //子线程标识
private Path mPath;
public SurfaceViewTest(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mHolder = getHolder();
mHolder.addCallback(this);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(10);
mPaint.setColor(Color.BLACK);
setFocusable(true);
mPath = new Path();
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
isDraw = true;
new Thread(this).start();
}
//Surface大小格式改变时
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isDraw = false;
mHolder.removeCallback(this);
}
@Override
public void run() {
while (isDraw) {
synchronized (mHolder) {
draw();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(x, y);
break;
}
return true;
}
//绘图逻辑
private void draw() {
try {
mCanvas = mHolder.lockCanvas();
if(mCanvas != null) {
//设置画布颜色
mCanvas.drawColor(Color.WHITE);
mCanvas.drawPath(mPath, mPaint);
}
} finally {
if(mCanvas != null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}