SurfaceView绘制触摸轨迹闪烁问题的最终解决方案
SurfaceView绘制触摸轨迹闪烁问题的最终解决方案,有需要的朋友可以参考下。
由于SurfaceView使用双缓存机制,两张画布轮流显示到屏幕上。那么,要存储触摸轨迹并避免两张画布内容不一致造成的闪烁问题,完全可以利用保存绘制过程并不断重新绘制的方法解决闪烁,而且这样还顺带解决了多次试验中偶尔出现的因为moveTo()函数不能读取到参数执行默认设置(参数设为上次的触摸点)而出现的断线连接闪烁问题,详细代码如下:
package com.tobacco.touchdraw;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnTouchListener;
public class LSurfaceView extends SurfaceView implements Callback,OnTouchListener,Runnable{
private SurfaceHolder sfh;
private Canvas canvas;
private Paint paint;
private Path path;
private ArrayList<Path> paths;
private boolean flag;
public LSurfaceView(Context context) {
super(context);
sfh=this.getHolder();
sfh.addCallback(this);
paint=new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStrokeWidth(4);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paths=new ArrayList<Path>();
path=new Path();
}
public void myDraw(MotionEvent e){
int action=e.getAction();
switch(action){
case MotionEvent.ACTION_DOWN:
path.moveTo(e.getX(),e.getY());
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(e.getX(),e.getY());
break;
case MotionEvent.ACTION_UP:
//path.close();
Path path1=new Path(path);
paths.add(path1);
path.reset();
break;
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
flag=true;
setOnTouchListener(this);
new Thread(this).start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag=false;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
myDraw(event);
return true;
}
@Override
public void run() {
while(flag){
long start=System.currentTimeMillis();
canvas=sfh.lockCanvas();
if(canvas!=null){
canvas.drawColor(Color.BLACK);
for(int i=0;i<paths.size();i++)
canvas.drawPath(paths.get(i),paint);
canvas.drawPath(path,paint);
sfh.unlockCanvasAndPost(canvas);
}
long end=System.currentTimeMillis();
try{
if(end-start<30){
Thread.sleep(30-(end-start));
}
}
catch(Exception e){
}
}
}
}
这里还要注意的是:ArrayList保存的是对象的引用,所以要在每次添加时都新建一个对象实体。