我创建了一个应用程序来绘制并想要实现undo / redo的功能,我尝试了各种方法,但是没有一个工作,有人可以帮我吗?
这是我的代码:
变量
'public class MainDrawingView extends View {
public MainDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
float TOUCH_TOLERANCE = 4;
float mX, mY;
//drawing path
private Path drawPath, drawX, drawY;
//drawing and canvas paint
private Paint drawPaint;
private Paint canvasPaint;
private View canvasback;
private Paint bccanvas;
//initial color
private int paintColor = 0xFF000000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap, trans;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();'
SetupDrawing
'private void setupDrawing() {
drawPath = new Path();
drawPaint = new Paint();
bccanvas = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(20);
drawPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}'
onSizeChanged
'@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);
}'
触摸事件
'private void touch_start(float x, float y) {
undonePaths.clear();
drawPath.reset();
drawPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx, dy;
dx = Math.abs(x - mX);
dy = Math.abs(y - mY);
if ((dx >= TOUCH_TOLERANCE) || (dy >= TOUCH_TOLERANCE)) {
drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
drawPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
drawPath.lineTo(mX, mY);
// commit the path to our offscreen
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
drawPath.moveTo(mX, mY);
mX = x;
mY = y;
}
}
private void touch_up() {
drawPath.reset();
}'
的onTouchEvent
'public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
drawPath.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
drawPath.lineTo(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
drawPath.reset();
touch_up();
invalidate();
break;
}
return true;
}'
的onDraw
'@SuppressLint("NewApi")
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(p, drawPaint);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
}'
onClickUndo
'public void onClickUndo () {
if (paths.size()>0){
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
undonePaths.clear();
}
else
{
}
//toast the user
}'
onClickRedo
'public void onClickRedo (){
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
else
{
}
//toast the user
}'
答案 0 :(得分:0)
TL; DR
几个月前我在Java Swing中创建了一个类似的应用程序。我实现这两种方法的方式是我创建了一个堆栈形状,当用户向白板添加形状然后从此推送/弹出以撤消/重做时(存储在临时变量中删除的形状) )
protected Shape removed; //shape object of an undo-ed object
protected Stack<Shape> shapes = new Stack<Shape>(); //stack to store the shapes
public void undo()
{
if (!shapes.empty()) //only undo if there's shapes on the board
{
removed = shapes.pop(); //pop removes a shape and returns it into 'removed' object
repaint();
}
}
public void redo()
{
if (removed != null) //only redo if something has been undone
{
shapes.push(removed); //push adds the object back onto the stack
removed = null;
repaint();
}
}
我希望这有帮助!
答案 1 :(得分:0)
一个好的方法是创建一个名为“Undoable”的界面。它至少有3个覆盖:do(),undo()和redo()。然后在实现Undoable的类中完成所有工作,并保留一堆这些=撤消历史记录。