2012-09-06 2 views
5

Dans ma Paint App, j'ai implémenté la fonction UNDO et fonctionne correctement. Mais si vous modifiez la couleur du pinceau (ou) le pinceau, tous mes tracés précédents seront remplacés par la nouvelle couleur de peinture. Le code est le suivant:Comment changer la couleur de la peinture/trait après l'implémentation de la fonction UNDO dans la peinture de peinture

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

après que vous annulez, vous devez appeler invalidate sans params qui conduit à la mise à jour de l'écran entier pour les couleurs de fonction précédente avec params qui specificy la partie will-be-mise à jour de l'écran, vous invalidez maintenant callign()() les touches changent aussi. –

Répondre

1

Ceci est une vieille question, mais je voulais laisser une réponse à tous ceux qui viennent ici. La solution consiste à garder une trace des instances Paint séparées pour chaque trait (il devrait y avoir exactement 1 objet Paint par objet Path).

Modifiez votre méthode touch_up pour réinitialiser le mPaint, en plus de réinitialiser le 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); 
} 

Ensuite, votre méthode onDraw ressemble à ceci.

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