2015-11-25 35 views
0

還有其他幾個類似於我的問題,我已經按照每種可能的方式執行了他們的答案,但這似乎不適用於我的代碼。我接近解決方案,但似乎缺少的東西。請幫忙,我要求不要將問題標記爲重複。在Android畫布上取消功能

這裏是在MainActivity:

public class MainActivity extends Activity implements View.OnClickListener    { 

// private ArrayList<Path> paths = new ArrayList<Path>(); 
// private ArrayList<Path> undonePaths = new ArrayList<Path>(); 

private Button btnUndo; 

public DrawingView drawView; 

//buttons 
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn, opacityBtn; 


//sizes 
private float smallBrush, mediumBrush, largeBrush; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 


    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    drawView = (DrawingView) findViewById(R.id.drawing); 

    //get the palette and first color button 
    LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors); 
    currPaint = (ImageButton) paintLayout.getChildAt(0); 
    currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); 

    //sizes from dimensions 
    smallBrush = 10; 
    mediumBrush = 20; 
    largeBrush = 30; 

    //draw button 
    drawBtn = (ImageButton) findViewById(R.id.draw_btn); 
    drawBtn.setOnClickListener(this); 

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

    //opacity 
    opacityBtn = (ImageButton) findViewById(R.id.opacity_btn); 
    opacityBtn.setOnClickListener(this); 



    btnUndo = (Button) findViewById(R.id.btnUndo); 
    btnUndo.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      drawView.undo(); 
     } 
    }); 
} 




@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

//user clicked paint 
public void paintClicked(View view) { 
    //use chosen color 
    //set erase false 
    drawView.setErase(false); 
    drawView.setPaintAlpha(100); 
    drawView.setBrushSize(drawView.getLastBrushSize()); 

    if (view != currPaint) { 
     ImageButton imgView = (ImageButton) view; 
     String color = view.getTag().toString(); 
     drawView.setColor(color); 
     //update ui 
     imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed)); 
     currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint)); 
     currPaint = (ImageButton) view; 
    } 
} 

@Override 
public void onClick(View view) { 

    if (view.getId() == R.id.draw_btn) { 
     //draw button clicked 
     final Dialog brushDialog = new Dialog(this); 
     brushDialog.setTitle("Brush size:"); 
     brushDialog.setContentView(R.layout.brush_chooser); 
     //listen for clicks on size buttons 
     ImageButton smallBtn = (ImageButton) brushDialog.findViewById(R.id.small_brush); 
     smallBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       drawView.setErase(false); 
       drawView.setBrushSize(smallBrush); 
       drawView.setLastBrushSize(smallBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     ImageButton mediumBtn = (ImageButton) brushDialog.findViewById(R.id.medium_brush); 
     mediumBtn.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       drawView.setErase(false); 
       drawView.setBrushSize(mediumBrush); 
       drawView.setLastBrushSize(mediumBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     ImageButton largeBtn = (ImageButton) brushDialog.findViewById(R.id.large_brush); 
     largeBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       drawView.setErase(false); 
       drawView.setBrushSize(largeBrush); 
       drawView.setLastBrushSize(largeBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     //show and wait for user interaction 
     brushDialog.show(); 

    } 


    else if (view.getId() == R.id.erase_btn) { 
     //switch to erase - choose size 
     final Dialog brushDialog = new Dialog(this); 
     brushDialog.setTitle("Eraser size:"); 
     brushDialog.setContentView(R.layout.brush_chooser); 
     //size buttons 
     ImageButton smallBtn = (ImageButton) brushDialog.findViewById(R.id.small_brush); 
     smallBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       drawView.setErase(true); 
       drawView.setBrushSize(smallBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     ImageButton mediumBtn = (ImageButton) brushDialog.findViewById(R.id.medium_brush); 
     mediumBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       drawView.setErase(true); 
       drawView.setBrushSize(mediumBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     ImageButton largeBtn = (ImageButton) brushDialog.findViewById(R.id.large_brush); 
     largeBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       drawView.setErase(true); 
       drawView.setBrushSize(largeBrush); 
       brushDialog.dismiss(); 
      } 
     }); 
     brushDialog.show(); 
    } else if (view.getId() == R.id.new_btn) { 
     //new button 
     AlertDialog.Builder newDialog = new AlertDialog.Builder(this); 
     newDialog.setTitle("New drawing"); 
     newDialog.setMessage("Start new drawing (you will lose the current drawing)?"); 
     newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       drawView.startNew(); 
       dialog.dismiss(); 
      } 
     }); 
     newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.cancel(); 
      } 
     }); 
     newDialog.show(); 
    } else if (view.getId() == R.id.save_btn) { 
     //save drawing 
     AlertDialog.Builder saveDialog = new AlertDialog.Builder(this); 
     saveDialog.setTitle("Save drawing"); 
     saveDialog.setMessage("Save drawing to device Gallery?"); 
     saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       //save drawing 
       drawView.setDrawingCacheEnabled(true); 
       //attempt to save 
       String imgSaved = MediaStore.Images.Media.insertImage(
         getContentResolver(), drawView.getDrawingCache(), 
         UUID.randomUUID().toString() + ".png", "drawing"); 
       //feedback 
       if (imgSaved != null) { 
        Toast savedToast = Toast.makeText(getApplicationContext(), 
          "Drawing saved to Gallery!", Toast.LENGTH_SHORT); 
        savedToast.show(); 
       } else { 
        Toast unsavedToast = Toast.makeText(getApplicationContext(), 
          "Oops! Image could not be saved.", Toast.LENGTH_SHORT); 
        unsavedToast.show(); 
       } 
       drawView.destroyDrawingCache(); 
      } 
     }); 
     saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       dialog.cancel(); 
      } 
     }); 
     saveDialog.show(); 
    } 

/* else if (view.getId() == R.id.btnUndo) { 
     //undo drawing 
     { 
      //drawView.setErase(true); 
      drawView.undo(); 

      /* if (paths.size() > 0) { 
       // drawView.setErase(true); 
       undonePaths.add(paths.remove(paths.size() - 1)); 
       view.invalidate(); 
      } else { 
       Toast.makeText(getBaseContext(), "undo isnt working", Toast.LENGTH_SHORT).show(); 
      }*/ 


      else if (view.getId() == R.id.opacity_btn) { 
       //launch opacity chooser 
       final Dialog seekDialog = new Dialog(this); 
       seekDialog.setTitle("Opacity level:"); 
       seekDialog.setContentView(R.layout.opacity_chooser); 
       //get ui elements 
       final TextView seekTxt = (TextView) seekDialog.findViewById(R.id.opq_txt); 
       final SeekBar seekOpq = (SeekBar) seekDialog.findViewById(R.id.opacity_seek); 
       //set max 
       seekOpq.setMax(100); 
       //show current level 
       int currLevel = drawView.getPaintAlpha(); 
       seekTxt.setText(currLevel + "%"); 
       seekOpq.setProgress(currLevel); 
       //update as user interacts 
       seekOpq.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 

        @Override 
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
         seekTxt.setText(Integer.toString(progress) + "%"); 
        } 

        @Override 
        public void onStartTrackingTouch(SeekBar seekBar) { 
        } 

        @Override 
        public void onStopTrackingTouch(SeekBar seekBar) { 
        } 

       }); 
       //listen for clicks on ok 
       Button opqBtn = (Button) seekDialog.findViewById(R.id.opq_ok); 
       opqBtn.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         drawView.setPaintAlpha(seekOpq.getProgress()); 
         seekDialog.dismiss(); 
        } 
       }); 
       //show dialog 
       seekDialog.show(); 
      } 
     } 
    } 

DrawingView.java:

(撤銷功能是在這個類的底部)

public class DrawingView extends View{ 

private ArrayList<Path> paths = new ArrayList<Path>(); 
private ArrayList<Path> undonePaths = new ArrayList<Path>(); 

private Path drawPath; 
//drawing and canvas paint 
private Paint drawPaint, canvasPaint; 
//initial color 
private int paintColor = 0xFF660000, paintAlpha = 255; 
//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(); 


} 

private void setupDrawing() { 

    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); 
    // paths.add(drawPath); 
} 

@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) { 
    for (Path path : paths) { 
     canvas.drawPath(path, drawPaint); 
    } 
    canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 

    canvas.drawPath(drawPath, drawPaint); 
} 

//register user touches as drawing action 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float touchX = event.getX(); 
    float touchY = event.getY(); 
    //respond to down, move and up events 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      drawPath.moveTo(touchX, touchY); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      drawPath.lineTo(touchX, touchY); 
      break; 
     case MotionEvent.ACTION_UP: 
      drawPath.lineTo(touchX, touchY); 
      drawCanvas.drawPath(drawPath, drawPaint); 
      drawPath.reset(); 
      break; 
     default: 
      return false; 
    } 
    //redraw 
    invalidate(); 
    return true; 

} 

//update color 
public void setColor(String newColor) { 
    invalidate(); 
    //check whether color value or pattern name 
    if (newColor.startsWith("#")) { 
     paintColor = Color.parseColor(newColor); 
     drawPaint.setColor(paintColor); 
     drawPaint.setShader(null); 
    } else { 
     //pattern 
     int patternID = getResources().getIdentifier(
       newColor, "drawable", "com.example.drawingfun"); 
     //decode 
     Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID); 
     //create shader 
     BitmapShader patternBMPshader = new BitmapShader(patternBMP, 
       Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 
     //color and shader 
     drawPaint.setColor(0xFFFFFFFF); 
     drawPaint.setShader(patternBMPshader); 
    } 
} 

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

//return current alpha 
public int getPaintAlpha() { 
    return Math.round((float) paintAlpha/255 * 100); 
} 

//set alpha 
public void setPaintAlpha(int newAlpha) { 
    paintAlpha = Math.round((float) newAlpha/100 * 255); 
    drawPaint.setColor(paintColor); 
    drawPaint.setAlpha(paintAlpha); 
} 

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

     Toast.makeText(getContext(), "undo isnt working wth", Toast.LENGTH_SHORT).show(); 
    } 
} 
} 
+0

prolly因爲你沒有做什麼很明顯像在創建新的路徑,並把它放入數組「上下來「...在」繪製「你應該顯然從這個數組中繪製所有路徑 – Selvin

回答

0

我有這個今天早些時候有類似的問題,這是一張相當老的票,所以我不確定你是否還有興趣...但是其他人可能會。

我認爲這個問題是,你永遠只用路徑的一個實例 - 它有點怪,但道路並不僅僅指向AB

我想你需要做的是使新的路徑之前,把他們到你的收藏 - Selvin在他的評論中說。

例如,你可以做這樣的事情;

public boolean onTouchEvent(MotionEvent event) { 
float touchX = event.getX(); 
float touchY = event.getY(); 
//respond to down, move and up events 
switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     //Make a new instance of DrawPath 
     drawPath = new Path(); 
     drawPath.moveTo(touchX, touchY); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     drawPath.lineTo(touchX, touchY); 
     break; 
    case MotionEvent.ACTION_UP: 
     drawPath.lineTo(touchX, touchY); 
     drawCanvas.drawPath(drawPath, drawPaint); 
     drawPath.reset(); 
     break; 
    default: 
     return false; 
} 
//redraw 
invalidate(); 
return true; 

}

當你做路徑休息我懷疑這是在清除繪製的所有行 - 這是因爲他們都是一個路徑(儘管幾間觸摸事件已經使他們) 。

如果這不工作讓我知道什麼是真正的問題 - 是不是出現行等等