我需要写手指画应用程序。我需要对绘制的曲线进行一些计算,所以我认为使用SurfaceView
但不是View
.
我已经编写了绘图代码。我将点收集到 Path 中并绘制它。在 ACTION_UP 上,此路径正在重置。在绘图循环中,我只绘制最后一条路径。
但由于某种原因,以前的路径也被重新绘制。这会导致烦人的眨眼,这是我不想要的。我在每个绘制周期都改变了线条颜色,我看到,以前的路径改变了它们的颜色,尽管没有代码来收集和重绘它们。
为什么这样?有什么办法可以让 SurfaceView 不重复之前的所有图纸?
这是我的代码:
public class OtherDrawView extends SurfaceView implements SurfaceHolder.Callback {
private DrawingThread mThread;
private Path mPath;
private static final Object lock = new Object();
public OtherDrawView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
mThread = new DrawingThread(surfaceHolder);
mPath = new Path();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath.moveTo(event.getX(), event.getY());
continueDrawingThread();
return true;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(event.getX(), event.getY());
continueDrawingThread();
return true;
case MotionEvent.ACTION_UP:
mPath.reset();
return true;
}
return false;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mThread.setRunning(true);
mThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
mThread.setRunning(false);
continueDrawingThread();
while (retry) {
try {
mThread.join();
retry = false;
}
catch (InterruptedException ignored) { }
}
}
private void continueDrawingThread() {
synchronized (lock) {
try {
lock.notifyAll();
} catch (Exception ignored) {}
}
}
private class DrawingThread extends Thread {
private boolean mRunning;
private Paint mPaint;
private Random mRandom = new Random(System.currentTimeMillis());
private final SurfaceHolder mSurfaceHolder;
public DrawingThread(SurfaceHolder surfaceHolder) {
mSurfaceHolder = surfaceHolder;
mPaint = new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);
}
public void setRunning(boolean running) {
mRunning = running;
}
private void drawPath() {
Canvas canvas = null;
try {
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
assert canvas != null;
mPaint.setColor(Color.rgb(mRandom.nextInt(255), mRandom.nextInt(255), mRandom.nextInt(255)));
canvas.drawPath(mPath, mPaint);
}
}
catch (Exception ignored) { }
finally {
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
@Override
public void run() {
while (mRunning) {
drawPath();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException ignored) {
}
}
}
}
}
}