Je développe l'application de dessin, dans lequel l'utilisateur peut dessiner des formes comme le rectangle, le cercle, etc. L'utilisateur peut également faire un dessin à main levée (stylo).Annuler et rétablir sur la toile
Je souhaite ajouter une fonction d'annulation, de rétablissement. J'ai recherché et lu la plupart de réponse de SO pour annuler et refaire, mais tous sont liés aux chemins. Cela signifie qu'ils gèrent deux listes, une pour la liste des chemins tracée ou la seconde pour annuler la liste des chemins. C'est une bonne façon de travailler, mais c'est SEULEMENT si c'est un dessin à main levée ou si je travaille avec des chemins.
Ici j'appelle différents types de méthodes de toile pour différentes formes.
Aidez-moi à fournir l'annulation de dessin sur toile.
Voici mon code
public class DrawingView extends android.support.v7.widget.AppCompatImageView {
public static final int RECTANGLE = 1;
public static final int SQUARE = 2;
public static final int CIRCLE = 3;
public
static final int LINE = 4;
public static final int SMOOTH_LINE = 5;
public static final int TRIANGLE = 6;
public static final int IMPORT_IMAGE = 7;
public static final int ERASER = 8;
private static final float TOUCH_TOLERANCE = 5;
private int color;
private int currentShape;
protected Paint mPaint;
protected Bitmap mBitmap;
protected Canvas mCanvas;
private float mx, my;
private float mStartX, mStartY;
private int width, height;
private boolean isDrawing = true;
public static int TOUCH_STROKE_WIDTH = 3;
public static int ERASER_WIDTH = 3;
private Path mPath = new Path();
int countTouch = 0;
float basexTriangle = 0;
float baseyTriangle = 0;
public DrawingView(Context context, int shape, int color) {
super(context);
initPaint();
}
protected void initPaint() {
color = DrawingActivity.selectedColor;
currentShape = DrawingActivity.currentShape;
mPaint = new Paint(Paint.DITHER_FLAG);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(color);
if (DrawingActivity.isFill && !DrawingActivity.isEraser && currentShape != SMOOTH_LINE) {
mPaint.setStyle(Paint.Style.FILL);
} else {
mPaint.setStyle(Paint.Style.STROKE);
}
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
if (DrawingActivity.isEraser) {
mPaint.setStrokeWidth(ERASER_WIDTH);
} else {
mPaint.setStrokeWidth(TOUCH_STROKE_WIDTH);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//Retrieve the point
mx = event.getX();
my = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initPaint();
break;
}
switch (currentShape) {
case RECTANGLE:
onTouchEventRectangle(event);
break;
case SQUARE:
onTouchEventSquare(event);
break;
case CIRCLE:
onTouchEventCircle(event);
break;
case LINE:
onTouchEventLine(event);
break;
case SMOOTH_LINE:
onTouchEventSmoothLine(event);
break;
case TRIANGLE:
onTouchEventTriangle(event);
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
if (isDrawing) {
switch (currentShape) {
case RECTANGLE:
onDrawRectangle(canvas);
break;
case SQUARE:
onDrawSquare(canvas);
break;
case CIRCLE:
onDrawCircle(canvas);
break;
case LINE:
onDrawLine(canvas);
break;
case SMOOTH_LINE:
onDrawLine(canvas);
break;
case TRIANGLE:
onDrawTriangle(canvas);
break;
}
}
//draw your element
}
private void onTouchEventRectangle(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrawing = true;
mStartX = mx;
mStartY = my;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
isDrawing = false;
drawRectangle(mCanvas, mPaint);
invalidate();
break;
}
}
private void onDrawRectangle(Canvas canvas) {
drawRectangle(canvas, mPaint);
}
private void drawRectangle(Canvas canvas, Paint paint) {
float right = mStartX > mx ? mStartX : mx;
float left = mStartX > mx ? mx : mStartX;
float bottom = mStartY > my ? mStartY : my;
float top = mStartY > my ? my : mStartY;
canvas.drawRect(left, top, right, bottom, paint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
mCanvas = new Canvas(mBitmap);
}
private void onDrawSquare(Canvas canvas) {
onDrawRectangle(canvas);
}
private void onTouchEventSquare(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrawing = true;
mStartX = mx;
mStartY = my;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
adjustSquare(mx, my);
invalidate();
break;
case MotionEvent.ACTION_UP:
isDrawing = false;
adjustSquare(mx, my);
drawRectangle(mCanvas, mPaint);
invalidate();
break;
}
}
/**
* Adjusts current coordinates to build a square
*
* @param x
* @param y
*/
protected void adjustSquare(float x, float y) {
float deltaX = Math.abs(mStartX - x);
float deltaY = Math.abs(mStartY - y);
float max = Math.max(deltaX, deltaY);
mx = mStartX - x < 0 ? mStartX + max : mStartX - max;
my = mStartY - y < 0 ? mStartY + max : mStartY - max;
}
private void onDrawCircle(Canvas canvas) {
canvas.drawCircle(mStartX, mStartY, calculateRadius(mStartX, mStartY, mx, my), mPaint);
}
private void onTouchEventCircle(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrawing = true;
mStartX = mx;
mStartY = my;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
isDrawing = false;
mCanvas.drawCircle(mStartX, mStartY,
calculateRadius(mStartX, mStartY, mx, my), mPaint);
invalidate();
break;
}
}
/**
* @return
*/
protected float calculateRadius(float x1, float y1, float x2, float y2) {
return (float) Math.sqrt(
Math.pow(x1 - x2, 2) +
Math.pow(y1 - y2, 2)
);
}
private void onDrawLine(Canvas canvas) {
float dx = Math.abs(mx - mStartX);
float dy = Math.abs(my - mStartY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
canvas.drawLine(mStartX, mStartY, mx, my, mPaint);
}
}
private void onTouchEventLine(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrawing = true;
mStartX = mx;
mStartY = my;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
isDrawing = false;
mCanvas.drawLine(mStartX, mStartY, mx, my, mPaint);
invalidate();
break;
}
}
private void onTouchEventSmoothLine(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrawing = true;
mStartX = mx;
mStartY = my;
mPath.reset();
mPath.moveTo(mx, my);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(mx - mStartX);
float dy = Math.abs(my - mStartY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mStartX, mStartY, (mx + mStartX)/2, (my + mStartY)/2);
mStartX = mx;
mStartY = my;
}
mCanvas.drawPath(mPath, mPaint);
invalidate();
break;
case MotionEvent.ACTION_UP:
isDrawing = false;
mPath.lineTo(mStartX, mStartY);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
invalidate();
break;
}
}
private void onDrawTriangle(Canvas canvas) {
if (countTouch < 3) {
canvas.drawLine(mStartX, mStartY, mx, my, mPaint);
} else if (countTouch == 3) {
canvas.drawLine(mx, my, mStartX, mStartY, mPaint);
canvas.drawLine(mx, my, basexTriangle, baseyTriangle, mPaint);
}
}
private void onTouchEventTriangle(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
countTouch++;
if (countTouch == 1) {
isDrawing = true;
mStartX = mx;
mStartY = my;
} else if (countTouch == 3) {
isDrawing = true;
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
invalidate();
break;
case MotionEvent.ACTION_UP:
countTouch++;
isDrawing = false;
if (countTouch < 3) {
basexTriangle = mx;
baseyTriangle = my;
mCanvas.drawLine(mStartX, mStartY, mx, my, mPaint);
} else if (countTouch >= 3) {
mCanvas.drawLine(mx, my, mStartX, mStartY, mPaint);
mCanvas.drawLine(mx, my, basexTriangle, baseyTriangle, mPaint);
countTouch = 0;
}
invalidate();
break;
}
}
public void clearDrawing()
{
setDrawingCacheEnabled(false);
onSizeChanged(width, height, width, height);
invalidate();
setDrawingCacheEnabled(true);
}
/**
* Getter of currentShape
*/
public int getCurrentShape() {
return currentShape;
}
/**
* Setter of currentShape
*/
public void setCurrentShape(int currentShape) {
this.currentShape = currentShape;
}
}
Et est un problème? Undoing formes? – CoolMind