2

我正在开发一个绘图应用程序。它相当简单,使用 onTouchEvent、paths 和 canvas.drawPath。每当用户不停地快速滑动并释放时,路径的最后一段会持续闪烁。在 ACTION_UP 条件下,我更新路径并将布尔 resetPath 设置为 true,在 onDraw 中,我绘制路径,如果 resetPath 为 true,我调用 path.reset(),然后将 resetPath 设置为 false。我究竟做错了什么?

    class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
    private DrawingThread _thread;
    private Path path;
    private Boolean resetPath = false;

    public DrawingPanel(Context context) {
        super(context);
        getHolder().addCallback(this);
        _thread = new DrawingThread(getHolder(), this);
        path = new Path();
    }


    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 25;



    public boolean onTouchEvent(MotionEvent event) {

        synchronized (_thread.getSurfaceHolder()) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                path.reset();
                path = new Path();
                path.moveTo(event.getX(), event.getY());
                mX = event.getX();
                mY = event.getY();
            }else if(event.getAction() == MotionEvent.ACTION_MOVE){
                float dx = Math.abs(event.getX() - mX);
                float dy = Math.abs(event.getY() - mY);
                if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                    path.quadTo(mX, mY, (event.getX() + mX)/2, (event.getY() + mY)/2);
                    mX = event.getX();
                    mY = event.getY();
                }
            }else if(event.getAction() == MotionEvent.ACTION_UP){
                resetPath = true;
            }
            return true;
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path, mPaint);
        if (resetPath) {
            path.reset();
            resetPath = false;
        }
    }
4

1 回答 1

0

考虑以下

  1. onDraw中,您不会在绘制路径之前绘制或重置整个画布。通常情况下,你应该。如果不是,它总是在前一个位图的顶部绘制路径。如果您的绘画使用透明度,由于重叠,您绘制的路径的最旧部分的透明度将低于最新部分。
  2. OnTouchEvent并且onDraw不要在同一个线程上运行。
  3. SurfaceView透明地使用双缓冲技术。两次连续调用onDraw将绘制到两个不同的画布。因此,如果在两次调用 之间存在ACTION_MOVEand ,则第二个缓冲区将比第一个缓冲区拥有更多的绘图。这就是为什么你有你的眨眼效果。ACTION_UPonDraw

解决方案

更改resetPath为整数,以便您可以在重置之前绘制两次路径。

private int resetPath = 0;

...else if(event.getAction() == MotionEvent.ACTION_UP){
            resetPath = 2;
   }...

public void onDraw(Canvas canvas) {
    canvas.drawPath(path, mPaint);
    if (resetPath == 1) {
        path.reset();
        resetPath = 0;
    } else if(resetPath == 2) {
        resetPath = 1
    }
}
于 2013-05-17T07:00:06.063 回答