2016-07-06 3 views
0

Я создал код, который делает снимок и отображает изображение, после чего пользователь может рисовать на картинке.Метод отмены отмены Android на холсте

Я хочу реализовать метод undo. Я основывал свой код на многих примерах, которые я читал. Проблема в моем методе onDraw - примеры не используют drawBitmap, но для меня мне нужно нарисовать растровое изображение на холсте, чтобы изображение появилось.

Показанный код показывает изображение, позволяет рисовать изображение, но не отменяет чертежи. Я не могу понять, что не так/как это исправить.

public class PhotoView extends View { 

    private Bitmap mBitmap; 
    private Canvas mCanvas; 
    private Path mPath; 
    private Paint mBitmapPaint; 
    private ArrayList<Path> paths = new ArrayList<>(); 

    public PhotoView(Context c) { 
     super(c); 
     mBitmap = mutableBitmap; 
     mPath = new Path(); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
     mCanvas = new Canvas(mBitmap); 
    } 

    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     //canvas.drawColor(0xFFAAAAAA); 
     ****must call in order for image to show up ***** 
     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
     //canvas.drawPath(mPath, mPaint); 
     for (Path p : paths){ 
      canvas.drawPath(p, mPaint); 
     } 
     canvas.drawPath(mPath, mPaint); //real time drawing on canvas 
    } 

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

    private void touchStart(float x, float y) { 
     mPath.reset(); 
     mPath.moveTo(x, y); 
     mX = x; 
     mY = y; 
    } 

    private void touchMove(float x, float y) { 
     float dx = Math.abs(x - mX); 
     float dy = Math.abs(y - mY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
      mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
      mX = x; 
      mY = y; 
     } 
    } 

    private void touchUp() { 
     mPath.lineTo(mX, mY); 
     // commit the path to our offscreen 
     mCanvas.drawPath(mPath, mPaint); 
     // kill this so we don't double draw 
     paths.add(mPath); 
     mPath = new Path(); 
     //mPath.reset(); 
     //paths.add(mPath); 
    } 

    public void onClickUndo() { 
     if (paths.size()>0) 
     { 
      paths.remove(paths.size()-1); 
      invalidate(); 
     } 
    } 
    public Bitmap getPic() { 
     mCanvas.save(); 
     return mBitmap; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     float x = event.getX(); 
     float y = event.getY(); 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       touchStart(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       touchMove(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_UP: 
       touchUp(); 
       invalidate(); 
       break; 
     } 
     return true; 
    } 
} 

ответ

0

Итак, есть две вещи, которые вы делаете, когда дело доходит до Paths, что привлекает пользователь.

  1. В методе touchUp(): mCanvas.drawPath(mPath, mPaint);
  2. В onDraw(): canvas.drawPath(p, mPaint);

При вызове onClickUndo(), то onDraw() вещи становится необратимо. Но одно в touchUp() не отменено. Вот почему ваш Undo не работает. Проблема в строке mCanvas.drawPath(mPath, mPaint);

Solution:
Не обратить mPath на mCanvas. Когда вы это сделаете, ваш mBitmap будет изменен (вы рисуете свой paths на mBitmap). Невозможно отменить это. И это не то, что вы хотите. Если вы хотите, чтобы ваш paths в вашем mBitmap, так что вы можете сохранить его в файле или так, сделайте это окончательно (возможно, у вас есть метод save() и сделайте это в этом методе).

Смежные вопросы