1

フィンガー ペイント アプリケーションを作成する必要があります。描かれた曲線についていくつかの計算が必要なので、 を使用するのは良い考えですが、 は使用SurfaceViewしない方がよいと思いますView

描画用のコードを書きました。ポイントをパスに集めて描画します。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) {
                    }
                }
            }
        }
    }
}
4

2 に答える 2