2012-09-06 53 views
5

在我的塗料應用程序中,我實現了UNDO功能,並且工作正常。但是如果改變畫筆顏色(或)畫筆描邊,那麼我所有以前繪製的路徑都將改變爲新的顏色。代碼如下:在油漆塗料中實現UNDO功能後如何改變塗料顏色/中風

public class CustomView extends View implements OnTouchListener { 
    public Canvas mCanvas; 
    private Path mPath; 
    public Paint mPaint, mBitmapPaint; 
    Bitmap mBitmap; 
    Canvas canvas; 
    public ArrayList<Path> paths = new ArrayList<Path>(); 
    public ArrayList<Path> undonePaths = new ArrayList<Path>(); 

    private Bitmap im; 

    public CustomView(Context context) { 
     super(context); 
     setFocusable(true); 
     setFocusableInTouchMode(true); 
     setOnTouchListener(this); 
     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(0xFFFFFFFF); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(6); 
     mCanvas = new Canvas(); 
     mPath = new Path(); 

     im = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher); 
     DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); 
     int w = metrics.widthPixels; 
     int h = metrics.heightPixels; 
     mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
     // mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); 
    } 

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

    @Override 
    protected void onDraw(Canvas canvas) { 
     // mPath = new Path(); 
     // canvas.drawPath(mPath, mPaint); 
     canvas.drawColor(Color.TRANSPARENT); 
     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
     for (Path p : paths) { 
      canvas.drawPath(p, mPaint); 
     } 
     canvas.drawPath(mPath, mPaint); 
    } 

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

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

    private void touch_move(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 touch_up() { 
     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(); 

    } 

    public void onClickUndo() { 
     if (paths.size() > 0) { 
      undonePaths.add(paths.remove(paths.size() - 1)); 
      invalidate(); 
     } else { 

     } 
     // toast the user 
    } 

    public void onClickRedo() { 
     if (undonePaths.size() > 0) { 
      paths.add(undonePaths.remove(undonePaths.size() - 1)); 
      invalidate(); 
     } else { 

     } 
     // toast the user 
    } 

    @Override 
    public boolean onTouch(View arg0, MotionEvent event) { 
     float x = event.getX(); 
     float y = event.getY(); 

     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      touch_start(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      touch_move(x, y); 
      invalidate(); 
      break; 
     case MotionEvent.ACTION_UP: 
      touch_up(); 
      invalidate(); 
      break; 
     } 
     return true; 
    } 
} 
+1

撤消後,你應該不PARAMS從而導致整個屏幕更新,以便以前的顏色調用無效()函數與specificy屏幕的意志被更新過的部分參數,可以立即callign無效()觸動也會改變。 –

回答

1

這是一個古老的問題,但我想留下一個答案,任何人來到這裏。解決方案是跟蹤每個筆劃的單獨Paint實例(每個Path對象應該只有1個Paint對象)。

改變你的touch_up方法來重置mPaint,除了重置mPath。

private void touch_up() { 
    mPath.lineTo(mX, mY); 
    mCanvas.drawPath(mPath, mPaint); 
    paths.add(mPath); 
    mPath = new Path(); 
    mPaints.add(mPaint) 
    // Creates a new Paint reference, but keeps the previous state (color, width, etc.) 
    mPaint = new Paint(mPaint); 
} 

然後你的onDraw方法看起來像這樣。

for (int i = 0; i < mPaths.size(); i++) { 
    canvas.drawPath(mPaths.get(i), mPaints.get(i)); 
}