如何在Android中的绘图应用程序中实现撤消功能?

时间:2012-03-26 13:00:08

标签: android graphics android-canvas undo-redo

我想在我的应用程序中执行撤消功能..为此我搜索到网络发现采取x,y点的arraylist我已经完成下面的代码我无法撤消图纸?

public Drawview(Context context, float x, float y, int r) {
            super(context);


            mBitmap = Bitmap.createBitmap(800, 1200, Bitmap.Config.ARGB_8888);
           // mainbitmap.add(mBitmap);
            //System.out.println("**mBitmapPaint***"+mBitmapPaint);
            mCanvas = new Canvas(mBitmap);
            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);



        }

       @Override
       protected void onSizeChanged(int w, int h, int oldw, int oldh) {
           super.onSizeChanged(w, h, oldw, oldh);
       }

        @Override 
        protected void onDraw(Canvas canvas) {

            System.out.println("***Drawinglines****"+Drawinglines);

                canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
                canvas.drawPath(mPath, mPaint);



        }


        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            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);
            mCanvas.drawPath(mPath, mPaint);
        ///    path.
            //graphics.add(mPath);
            mPath.reset();
        }

        // events when touching the screen
        public boolean onTouchEvent(MotionEvent event) {

             event.getAction();
            int eventaction = event.getAction(); 

            int X = (int)event.getX(); 
            int Y = (int)event.getY(); 

            switch (eventaction ) { 

            case MotionEvent.ACTION_DOWN: 

            {
                touch_start(X, Y);
                }
                 invalidate(); 
                 break; 


            case MotionEvent.ACTION_MOVE:  

                System.out.println("***ACTION_MOVE**************"+X+"************"+Y);
                if((Drawinglines.equals("Pen"))||(Drawinglines.equals("Erase")))
                {
                  touch_move(X, Y);
                  temp_point.add(new Point(X,Y));

                }
                invalidate(); 
                break; 

            case MotionEvent.ACTION_UP: 

                main_Points.add(temp_point);
                temp_point = null;

                 touch_up();  

                 invalidate(); 
                 break; 
            } 

            return true; 

        }




        public void undopath()
        {   
              main_Points.remove(main_Points.size()-1);
             invalidate();
        }

    }
    @Override
    public void onClick(View v) {


        if(v ==  Undo)
        {    
            Drawview abc=new Drawview();
             abc.undopath();
        }

但撤消撤消功能无效。

4 个答案:

答案 0 :(得分:1)

private Slate mSlate;
private TiledBitmapCanvas mTiledCanvas;

 public void clickUndo(View unused) {

        mSlate.undo();
    }


public void undo() {
        if (mTiledCanvas == null) {
            Log.v(TAG, "undo before mTiledCanvas inited");
        }
        mTiledCanvas.step(-1);

        invalidate();
    }

答案 1 :(得分:0)

我没有尝试,但我认为使用两个画布和位图是有帮助的,绘制当前状态,一个仍然是前状态,只需要恢复前一个。但它只能在步骤中恢复。

答案 2 :(得分:0)

这里有一些代码: 创建:

private Canvas mCanvas;
private Bitmap mBitmap;

private Canvas mRestoreCanvas;
private Bitmap mRestoreBitmap;

INIT:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mPictureWidth = w;
    mPictureHeight = h;

    Loge.i("mPictureWidth = " + mPictureWidth + " mPictureHeight = "
            + mPictureHeight);
    if (mCanvas == null && mBitmap == null && mPictureWidth > 0
            && mPictureHeight > 0) {
        mBitmap = Bitmap.createBitmap(mPictureWidth, mPictureHeight,
                Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        mCanvas.save();

        mRestoreBitmap = Bitmap.createBitmap(mPictureWidth, mPictureHeight,
                Bitmap.Config.ARGB_8888);
        mRestoreCanvas = new Canvas(mRestoreBitmap);
        mRestoreCanvas.save();
    }
    super.onSizeChanged(w, h, oldw, oldh);
}

的onDraw:

@Override
protected void onDraw(Canvas canvas) {
    if (mPattern == DRAW_LINE) {
        mCanvas.restore();
        mCanvas.drawPath(path, paint);
        mCanvas.save();
    }
    mCanvas.save();
    if (mBitmap != null)
        canvas.drawBitmap(mBitmap, 0, 0, null);
}

的onTouchEvent:

@Override
public boolean onTouchEvent(MotionEvent event) {

    if(event.getAction() == MotionEvent.ACTION_DOWN){
        mRestoreCanvas.drawBitmap(mBitmap, 0, 0, bitmapPaint);
    }

    if (mPattern == DRAW_LINE) {
        return drawLines(event);
    } else if (mPattern == DRAW_PATTERN) {
        return drawPattern(event);
    }
    return false;
}

撤消:

public void dust() {
    path.reset();
    mBitmap.recycle();
    mBitmap = Bitmap.createBitmap(mPictureWidth, mPictureHeight,
            Bitmap.Config.ARGB_8888);
    mCanvas.setBitmap(mBitmap);

    mCanvas.drawBitmap(mRestoreBitmap, 0, 0, bitmapPaint);

    invalidate();
}

测试好;

答案 3 :(得分:0)

嘿我用了一种技巧来删除黑线。在我的擦除按钮中,我将颜色设置为白色,而不是使用XferMode ..

  if(erase){
    paintColor = Color.parseColor(newColor);
    drawPaint.setColor(paintColor);
    }