2012-11-30 144 views
1

我尝试在使用Canvas的Android中绘制手指颜料。我已经使用颜料绘制当前路径的颜色。使用撤消重做选项移除和显示路径,但撤销重做效果很好。如果我使用另一种颜色绘制所有先前的路径,则将红色颜色改为当前颜色。Android - 在画布上绘制视图

import java.util.ArrayList; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.util.DisplayMetrics; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 

public class CustomView extends View implements OnTouchListener { 
    public Canvas mCanvas; 
    private Path mPath; 
    public Paint mPaint, mBitmapPaint; 
    Bitmap mBitmap; 
    Canvas canvas; 
    TabletActivity tabletActivity; 
    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); 
     this.setOnTouchListener(this); 
     mPaint = new Paint(); 
     mPaint.setAntiAlias(true); 
     mPaint.setDither(true); 
     mPaint.setColor(Color.RED); 
     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 
    } 


    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

您正在使用相同的画图对象来绘制前一个以及当前路径。

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    mPaint.setColor(Color.YELLOW); 
    for (Path p : paths) { 
     canvas.drawPath(p, mPaint); 
    } 
    mPaint.setColor(Color.RED); 
    canvas.drawPath(mPath, mPaint); 
} 
2

正如user603125所说,目前您只有一个绘画对象,并且使用该绘画绘制所有路径。请记住,在onDraw中,您每次都绘制全部路径。 要解决这个问题,您必须跟踪每条路径使用的颜色,例如在地图上,做一些像这样:

private Map<Path, Color> mPathColors = new HashMap<Path, Color>(); // map for path colors 
private Color mCurrentColor; // color to paint current path with (has to be set somewhere) 
... 
protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    for (Path p : paths) { 
     mPaint.setColor(mPathColors.get(p); 
     canvas.drawPath(p, mPaint); 
    } 
    mPaint.setColor(mCurrentColor); 
    canvas.drawPath(mPath, mPaint); 
} 

而且在touch_up()写入当前颜色的地图,像这样:

private void touch_up() { 
    ... 
    paths.add(mPath); 
    mPathColors.put(mPath, mCurrentColor); 
    ... 
}