Функции отмены и удаления в приложении для рисования Android (дубликат)

Этот вопрос задавался много раз, например, " Рисование в Android", "Стирание" и "Отмена действия", но ни у кого нет правильного решения. Я делаю приложение для рисования, и все работало нормально, пока я не добавил функцию отмены. После добавления функции отмены ластик не работает нормально. Это делает предыдущий рисунок черным и не стирает также. Это мой конструктор класса DrawingView:

public DrawingView(Context context){
    super(context);
    // if(!isInEditMode())
    setLayerType(View.LAYER_TYPE_SOFTWARE, drawPaint);

            drawPath = new Path();
    drawPaint = new Paint();
    drawPaint.setColor(paintColor);
    drawPaint.setAntiAlias(true);
    drawPaint.setStrokeWidth(35);
    drawPaint.setStyle(Paint.Style.STROKE);
    drawPaint.setStrokeJoin(Paint.Join.ROUND);
    drawPaint.setStrokeCap(Paint.Cap.ROUND);
    canvasPaint = new Paint(Paint.DITHER_FLAG);

}

Вот метод onDraw

@Override
protected void onDraw(Canvas canvas) {
//draw view

//  canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);

     for (Path p : paths)
        {
           drawPaint.setColor(colorsMap.get(p));
           drawPaint.setStrokeWidth(widthMap.get(p));
           canvas.drawPath(p, drawPaint);          
        } 
        drawPaint.setColor(paintColor);
        drawPaint.setStrokeWidth(30);

    if(erase){
        return;
    }
    canvas.drawPath(drawPath, drawPaint);
}

а вот сенсорный обработчик событий

@Override
public boolean onTouchEvent(MotionEvent event) {
//detect user touch     
    float touchX = event.getX();
    float touchY = event.getY();
    if(erase){
    //  drawPaint.setColor(paintColor);
        drawCanvas.drawPath(drawPath, drawPaint);
        invalidate();
    }

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
         undonePaths.clear();
           drawPath.reset();

        drawPath.moveTo(touchX, touchY);

        break;
    case MotionEvent.ACTION_MOVE:
         drawPath.lineTo(touchX, touchY);

        break;
    case MotionEvent.ACTION_UP:
        drawCanvas.drawPath(drawPath, drawPaint);
       if(!erase){
        paths.add(drawPath);
        colorsMap.put(drawPath,getDrawingColor());
        widthMap.put(drawPath,30);
       }
        drawPath = new Path();


        break;
    default:
        return false;
    }
    invalidate();
    return true;
}

вот мой метод SetErase

public void setErase(boolean isErase){
    //set erase true or false    
    erase=isErase;
    if(erase){
        drawPaint.setMaskFilter(null);
        drawPaint.setAlpha(0xFF);
        drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        } 
    else{ drawPaint.setXfermode(null);  
        }
    }

и последний мой метод отмены

public void onClickUndo() 
{ 
   if (paths.size()>0) 
    { 
       undonePaths.add(paths.remove(paths.size()-1));
       invalidate();
    }      
   else Toast.makeText(getContext(), "nothing more to undo", Toast.LENGTH_SHORT).show();
}

Нет ли способа реализовать функции отмены и удаления вместе в приложении для рисования? Если да? тогда, пожалуйста, предоставьте некоторую помощь. Спасибо

1 ответ

Это мой код Я мог стереть и отменить. Единственная проблема, которая у меня возникает, - когда я нажимаю на кисть, она постоянно стирается. Для перерисовки снова нужно выбрать цвет (не рисует с последним цветом). Если это работает, и вы можете это исправить, дайте мне знать, и я надеюсь, что помог.

public class DrawingView extends View {
private Context context;
private Path drawPath;
private Paint drawPaint;
private Paint canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private int previousPaintColor;
private int paintColor=0xFF000000;
private float brushSize;
private float eraserSize;
private float lastBrushSize;
private boolean isErasing = false;
private boolean isImageLoaded = false;
private List<PaintPathPair> undoList = null;
private List<PaintPathPair> currentMoveList = null;
private List<PaintPathPair> moveList = null;

public DrawingView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    this.moveList = new ArrayList<PaintPathPair>();
    this.undoList = new ArrayList<PaintPathPair>();
    this.currentMoveList = new ArrayList<PaintPathPair>();
    this.canvasPaint = new Paint(Paint.DITHER_FLAG);
    setupDrawing();
}

private void clearBrushes() {
    moveList.clear();
    undoList.clear();
    currentMoveList.clear();
}
private void setupDrawing() {
    drawPath = new Path();
    drawPaint = new Paint();

    brushSize = getResources().getInteger(R.integer.medium_size);
    lastBrushSize = brushSize;

    drawPaint.setColor(paintColor);
    drawPaint.setAntiAlias(true);
    drawPaint.setStrokeWidth(brushSize);
    drawPaint.setStyle(Paint.Style.STROKE);
    drawPaint.setStrokeJoin(Paint.Join.ROUND);
    drawPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
    if (isImageLoaded) {
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 
    }
    drawPaint.setColor(paintColor);
    for (PaintPathPair pair : currentMoveList) {
        canvas.drawPath(pair.getPath(), pair.getPaint());
    }
    for (PaintPathPair pair : moveList) {
        canvas.drawPath(pair.getPath(), pair.getPaint());   
    }
}
public void startNewDrawing() {
    setBackgroundColor(Color.WHITE);
    drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    clearBrushes();
    isImageLoaded = false;
    invalidate();
}
public void undo() {
    if (moveList.size() > 0) {
        undoList.add(moveList.remove(moveList.size() - 1));
        invalidate();   
    }
}
public void redo() {
    if (undoList.size() > 0) {
        moveList.add(undoList.remove(undoList.size() - 1));
        invalidate();
    }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    float touchX = event.getX();
    float touchY = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            drawPath.moveTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(touchX, touchY);
            currentMoveList.add(new PaintPathPair(drawPaint, drawPath));
            break;
        case MotionEvent.ACTION_UP:
            drawPath.lineTo(touchX, touchY);
            drawCanvas.drawPath(drawPath, drawPaint);
            moveList.add(new PaintPathPair(new Paint(drawPaint), drawPath));
            drawPath = new Path();
            currentMoveList.clear();
            break;
        default:
            return false;
    }
    invalidate();
    return true;
}

void setErasing(boolean erasing) {
    this.isErasing = erasing;
    int colorToSet = 0;
    previousPaintColor = drawPaint.getColor();

    if(isErasing) {
        //drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        this.setColor("#FFFFFFFF");
    }
    else {
        drawPaint.setXfermode(null);
    }
}
public void setColor(String newColor) {
    this.previousPaintColor = drawPaint.getColor();
    paintColor = Color.parseColor(newColor);
    drawPaint.setColor(paintColor);
    invalidate();
}
public float getBrushSize() {
    return brushSize;
}
public void setBrushSize(float newSize) {
    brushSize = newSize;
    drawPaint.setStrokeWidth(brushSize);
    setErasing(false);
}
public float getEraserSize() {
    return eraserSize;
}
public void setEraserSize(float newSize) {
    eraserSize = newSize;
    drawPaint.setStrokeWidth(eraserSize);
    setErasing(true);
}
public void setLastBrushSize(float lastBrushSize) {
    this.lastBrushSize = lastBrushSize;
}
public void setBackgroundImage(Bitmap image) {
    isImageLoaded = true;
    clearBrushes();
    canvasBitmap = image;
    drawCanvas.drawBitmap(image, new Matrix(), null);
    invalidate();
}
public float getLastBrushSize() {
    return lastBrushSize;
}   
}
Другие вопросы по тегам