您的位置:首页 > 移动开发 > Android开发

Android SurfaceView涂鸦板

2016-06-27 15:54 645 查看
频繁操作或者操作逻辑过长View容易造成主线程卡顿,可以用Surface来解决。

以下是两者的区别:

View主要适用于主动刷新,SurfaceView适用于被动刷新,例如频繁的刷新

View在主线程中对画面进行刷新,SurfaceView通过一个子线程进行刷新。

View在绘图时没有实现双缓冲机制,SurfaceView在底层实现中实现了双缓冲。

public class SimpleDraw extends SurfaceView
implements SurfaceHolder.Callback, Runnable {

private SurfaceHolder mHolder;
private Canvas mCanvas;
// 控制子线程的标志位
private boolean mIsDrawing;
private Path mPath;
private Paint mPaint;

public SimpleDraw(Context context) {
super(context);
initView();
}

public SimpleDraw(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}

public SimpleDraw(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
initView();
}

private void initView() {
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(40);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}

@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}

@Override
public void run() {
long start = System.currentTimeMillis();
while (mIsDrawing) {
draw();
}
long end = System.currentTimeMillis();
// 50 - 100 节省系统资源,休眠
if (end - start < 100) {
try {
Thread.sleep(100 - (end - start));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

private void draw() {
try {
// 取图层
mCanvas = mHolder.lockCanvas();
mCanvas.drawColor(Color.WHITE);
mCanvas.drawPath(mPath, mPaint);
} catch (Exception e) {
} finally {
if (mCanvas != null)
// 返回图层
mHolder.unlockCanvasAndPost(mCanvas);
}
}

@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;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: