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;
}
}
以下是两者的区别:
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;
}
}
相关文章推荐
- android 为支持多语言,常用的iso keystore country code
- Android 开源框架Universal-Image-Loader完全解析(三)---源代码解读
- Android开发LogUtil
- Android自定义组件开发详解笔记
- Android Handler
- Android studio更新到2.2之后出现的问题
- DrawerLayout的简单使用
- 你需要知道的Android拍照适配方案
- The Different between android folders(bin, xbin, sbin)
- Drawable /Bitmap、String/InputStream、Bitmap/byte[]互转
- Android Studio 使用 Github 托管代码
- AndroidStudio 混淆打包
- Android 自定义组合控件
- AndroidStudio 混淆打包
- (OK)(OK) install_quagga-0.99.21mr2.2_on_android-x86_64_in_Fedora23
- Android 跳转应用市场评分
- H.264视频在android手机端的解码与播放(转)
- Android内核开发:系统启动速度优化-Android OS启动优化(转)
- Android SDK和NDK
- Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解