2012-09-06 12 views
5

Boya Uygulamamda UNDO işlevini uyguladım ve iyi çalışıyor. Ancak boya fırçası rengini (veya) boya fırçasını değiştirirseniz, daha önce çizilen tüm yollarım yeni boya rengine dönüşür. Kod aşağıdaki gibidir:Tuval boyaında UNDO işlevini uyguladıktan sonra boya rengi/kontur nasıl değiştirilir?

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

, önceki renkleri böylece bütün ekran güncellemesi neden params olmadan ekranın irade-güncellenecektir kısmını specificy parametreler, artık callign invalidate() ile invalidate() işlevini çağırmalıdır dokunuşlar da değişir. –

cevap

1

Bu eski bir sorudur, ancak buraya gelen herkes için bir cevap bırakmak istedim. Çözüm, her vuruş için ayrı Paint örneklerini takip etmektir (Yol nesnesi için tam olarak 1 Paint nesnesi olmalıdır).

mPaint'i sıfırlamaya ek olarak, mPaint'i sıfırlamak için touch_up yönteminizi değiştirin.

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); 
} 

O zaman onDraw yönteminiz böyle bir şeye benziyor. Geri almak sonra

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