Erase functionality not working in Custom SurfaceView Android

I have a custom surfaceView which will paint the surface based on Touch event. When i draw something on this view it is working fine. But when i tried to erase the paint, nothing got erased. Please find the sample code snippet below:

public class MySurfaceView extends SurfaceView {
private static final String TAG = "FreeHandDrawing";
public static Canvas mCanvas;
SurfaceHolder holder;
private static Path path;
private Paint paint;
private ArrayList<Path> pathArrayList = new ArrayList<>();
private boolean freeHandMode;

public MySurfaceView(Context context, AttributeSet attrs) {
    super(context, attrs);
    freeHandMode = false;
    path = new Path();
    holder = getHolder();
    holder.setFormat(PixelFormat.TRANSPARENT);
    setDrawingCacheEnabled(true);

    this.setZOrderOnTop(true);

    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(0xFF22FF11);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(8);

}


@Override
public boolean onTouchEvent(MotionEvent event) {

    if(freeHandMode) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {

            Log.d("Action", "Placed");
            path.moveTo(event.getX(), event.getY());

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {

            Log.d("Action", "Moved");
            path.lineTo(event.getX(), event.getY());
            pathArrayList.add(path);

        }

        mCanvas = holder.lockCanvas();
        if (mCanvas != null) {
            if (pathArrayList.size() > 0) {

                mCanvas.drawPath(pathArrayList.get(pathArrayList.size() - 1), paint);

            }
            holder.unlockCanvasAndPost(mCanvas);

        } else {
            Log.d(TAG, "Canvas is NULL");
        }
    }
    invalidate();
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.d(TAG, "On draw called");

}

public void eraseDrawing() {
    pathArrayList.clear();
    invalidate();
}

public void drawEnableDisable(boolean mode) {
    freeHandMode = mode;
  }
}                                                  

What is the problem with the code above ?


You should keep your drawing code in the onDraw method

@Override
protected void onDraw(Canvas canvas) {
    // In case you want to delete/erase when path array/list is cleared.
    if (pathArrayList.size() == 0) {
        canvas.drawColor(0, Mode.CLEAR);
    }
    // In case, you want to draw all paths also in onDraw
    for(Path path : pathArrayList) {
        canvas.drawPath(path, paint);
    }
}

When you clear the Path Array(list) and then upon calling invalidate(), onDraw gets triggered.

Note: You're supposed to call invalidate() at the end of onTouchEvent() to tell the system to update the screen. Calling invalidate() will get the framework to eventually call onDraw().

Also you should NOT use canvas obtained by lockCanvas as it will not be hardware accelerated. Instead you should use the canvas passed as an argument to onDraw() itself.

You can choose to make the system a bit smart by not having to draw the pull list of paths every frame and instead handle erases/redraws etc by using special flags. And otherwise just render the latest path generated by the most recent call to onTouchEvent().

链接地址: http://www.djcxy.com/p/66776.html

上一篇: 如何将图像视图放在surfaceview android上

下一篇: 清除功能在自定义SurfaceView Android中不起作用