在android中擦除paintview中的问题

时间:2014-05-26 03:43:47

标签: android drawing android-canvas draw

MainActivity.java

public class MainActivity extends Activity implements OnClickListener {

private DrawingView drawView;
int mColor;
 String savedFilePath = "";
  public static  ArrayList<Path> undonePaths = new ArrayList<Path>();
public static  ArrayList<Path> paths = new ArrayList<Path>();
 //buttons
  Canvas bitmapCanvas;
 RelativeLayout  mRelativeLayoutScreenShot;
 static String mImagePath;
  private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
  //sizes
  private float smallBrush, mediumBrush, largeBrush;
  ImageButton mImageViewPicklColor;
   private boolean isFileAlreadySaved = false;

  ImageButton mImageButtonList;
  ImageButton mImageButtonShare;
  File file;
  Bitmap bitmap;
  Button mButtonUNDo;
  Dialog mDialogDate;
  Button mButtonRedo;
  boolean isStartAdl=false;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mDialogDate= new Dialog(MainActivity.this, android.R.style.Theme_NoTitleBar| android.R.style.Theme_Translucent|android.R.style.Theme_Holo_Dialog);
mDialogDate.setCancelable(true);
mDialogDate.requestWindowFeature(Window.FEATURE_NO_TITLE);
 }


@Override
protected void onResume() {

super.onResume();
savedFilePath="";
  mColor = 0xff0000ff;




    //get drawing view
      mButtonUNDo=(Button)findViewById(R.id.btn_undo);
      mButtonRedo=(Button)findViewById(R.id.btn_redo);
    drawView = (DrawingView)findViewById(R.id.drawing);
    mImageViewPicklColor=(ImageButton)findViewById(R.id.pick_color);
    RelativeLayout paintLayout = (RelativeLayout)findViewById(R.id.paint_colors);
    mImageButtonShare=(ImageButton)findViewById(R.id.share);
    mImageButtonList=(ImageButton)findViewById(R.id.list);
    mRelativeLayoutScreenShot=(RelativeLayout)findViewById(R.id.rr_draw);
    mImageButtonList.setOnClickListener(this);
    //sizes from dimensions
    smallBrush = getResources().getInteger(R.integer.small_size);
    mediumBrush = getResources().getInteger(R.integer.medium_size);
    largeBrush = getResources().getInteger(R.integer.large_size);

    //draw button
    drawBtn = (ImageButton)findViewById(R.id.draw_btn);
    drawBtn.setOnClickListener(this);
    File direct = new File(Environment.getExternalStorageDirectory() + "/androidpaint");

    if(!direct.exists())
     {
         if(direct.mkdir());//directory is created;

     }
    mImagePath = Environment.getExternalStorageDirectory() + "/androidpaint";
    //set initial size
    drawView.setBrushSize(mediumBrush);

    //erase button
    eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
    eraseBtn.setOnClickListener(this);

    //new button
    newBtn = (ImageButton)findViewById(R.id.new_btn);
    newBtn.setOnClickListener(this);

    //save button
    saveBtn = (ImageButton)findViewById(R.id.save_btn);
    saveBtn.setOnClickListener(this);
    mButtonRedo.setOnClickListener(this);
    mButtonUNDo.setOnClickListener(this);

    mImageViewPicklColor.setOnClickListener(this);
    mImageButtonShare.setOnClickListener(this);
    drawView.setErase(false);
    drawView.setBrushSize(drawView.getLastBrushSize());
    drawView.setColor(mColor);
    if (isStartAdl==true) {
        Intent intent = getIntent();
        finish();
        startActivity(intent);
    }


   }

   @Override
   public void onClick(View view){


   if (view.getId()==R.id.btn_undo) {

    System.out.println("UNDO "+paths.size());
    if (paths.size() > 0) {
        undonePaths.add(paths
                .remove(paths.size() - 1));
        drawView.invalidate();
     }
  }
   else if(view.getId()==R.id.erase_btn)
    {
       drawView.setErase(true);
    }
   else  if (view.getId()==R.id.btn_redo) {
           if (undonePaths.size()>0) {
               paths.add(undonePaths.remove(undonePaths.size()-1));
                drawView.invalidate();
           }
   }

  });
 } 

DrawingView.java

public class DrawingView extends View {

 private float mX, mY;
 private static final float TOUCH_TOLERANCE = 0;
 //drawing path
  private Path drawPath;
  //drawing and canvas paint
  private Paint drawPaint, canvasPaint;
  //initial color
  private int paintColor = 0xFF660000;
  //canvas
   private Canvas drawCanvas;
  //canvas bitmap
  private Bitmap canvasBitmap;
  //brush sizes
   private float brushSize, lastBrushSize;
  //erase flag
  private boolean erase=false;

  public DrawingView(Context context, AttributeSet attrs){
  super(context, attrs);

     setupDrawing();
 }

 //setup drawing
 private void setupDrawing(){

//prepare for drawing and setup paint stroke properties
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
System.out.println("cadslfjds");
MainActivity.paths.add(drawPath);
    }

//size assigned to view
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}

//draw the view - will be called after touch event
 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawColor(canvasPaints);
  for (Path p : MainActivity.paths) {
if(colorsMap.size()>0)
{

   drawPaint.setColor(colorsMap.get(p));
       canvas.drawPath(p, drawPaint);
}
}

drawPaint.setColor(paintColor);
canvas.drawPath(drawPath, drawPaint);

   private void touch_start(float x, float y) {
 drawPath.reset();
 drawPath.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) {
     drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
     mX = x;
     mY = y;
     }
   }

  private void touch_up() {
     drawPath.lineTo(mX, mY);
     drawCanvas.drawPath(drawPath, drawPaint);
     MainActivity.paths.add(drawPath);
     colorsMap.put(drawPath, paintColor);
     drawPath = new Path();
     drawPath.reset();
  }

  @Override
  public boolean onTouchEvent(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;
   }




   public void setColor(int newColor){
   invalidate();
  paintColor = newColor;
   drawPaint.setColor(paintColor);
  }

     //set brush size
   public void setBrushSize(float newSize){
 float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
        newSize, getResources().getDisplayMetrics());
  brushSize=pixelAmount;
  drawPaint.setStrokeWidth(brushSize);
 }

  //get and set last brush size
  public void setLastBrushSize(float lastSize){
   lastBrushSize=lastSize;
 }
  public float getLastBrushSize(){
  return lastBrushSize;
 }

 //set erase true or false
 public void setErase(boolean isErase){
 erase=isErase;
 if(erase)
      drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
 else 
     drawPaint.setXfermode(null);
   }

 //start new drawing
   public void startNew(){
  drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
 invalidate();
 }

当我绘制正常图片时,它将如下所示 first image

当我点击删除Button时,它将如下所示

Erase image

当我运行上面的代码时,问题是当我点击擦除按钮然后擦除不正常整个图片将其转换为黑色,所以任何想法我该如何解决?

2 个答案:

答案 0 :(得分:1)

你的代码看起来很完美,但问题是你在画布上设置白色作为背景,同时在画布上擦除,然后白色背景也被删除。因此,在擦除画布上的某些部分后,您必须再次设置白色背景。

@Override
    protected void onDraw(Canvas canvas) {
        //set background white
        canvas.drawColor(Color.WHITE);


        super.dispatchDraw(canvas);
    }

Check this demo code

答案 1 :(得分:0)

你在setErase中所做的只是设置一个porter duff模式。你实际上并没有重绘任何东西。您至少需要调用invalidate来更新屏幕。