开发者

Undo in a drawing app

开发者 https://www.devze.com 2023-03-05 05:15 出处:网络
Before I start I would like you to tell that I am using a very improper method for the \"undo\" operation.

Before I start I would like you to tell that I am using a very improper method for the "undo" operation. I have a drawing app which will save each strokes you draw on the view, and when you exit the app the final image will be copied to a folder and others will be deleted.

Now when you draw strokes on the view, each file will be saved in a temp. folder and the path of each file will be inserted to the database, this is to implement the undo operation. When the user clicks for undo, the last inserted value(path) will be deleted and the next path will be quired. My plan is to use this path to draw the image on the view, so each time the user 'undo's , the last path saved in the database will be deleted and the next path will be taken.

Hope you got my idea..! Now my issue is , I am not able to draw the image to the view, I have a custom view which draws the stokes.

View

public class MyView extends View {

        private static final float MINP = 0.25f;
        private static final float MAXP = 0.75f;

        private Bitmap  mBitmap;

        private Paint   mBitmapPaint;

        public MyView(Context c) {
            super(c);


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

            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

            mCanvas = new Canvas(mBitmap);
            mCanvas.drawColor(Color.BLACK);

         }

        @Override
        protected void onDraw(Canvas canvas) {

            try{

                 new SaveFileThread().execute(null);        //------->save strokes as files

                Log.i("In ondraw log", "Wow "+filename);

                if(undoflag=="undo" && nextp!="haha"){

                    String pat=UnDo();

                    if(pat!=null){

                        if(pat==filename){ pat=UnDo(); Log.i("undo called twice", "not again");}
                        else{

                        //  Bitmap nbmp=LoadBMPsdcard(pat);
                            //render the SD card image  
                      //      canvas.drawBitmap(nbmp, 0, 0, null);  

                        }
                    }
                    //the parent onDraw() method.  
                 //   super.onDraw(canvas);

                }


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

            }catch(Exception e){
                e.printStackTrace();
            }

        }

        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);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, mPaint);
            // kill this so we don't double draw
            mPath.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;
        }
    }

I have a thread that will do the saving, How can I draw an image from the SD card to this view.

Can any one suggest me any better ideas to do this. It would be a great help if you have some sample code if you bring a different idea.

Thanks in advance

Happy Coding


Well, I would not store the bitmaps in files at all. If it's a simple drawing app, then you could (I would) just have an arrayList of say 20 Bitmaps and store the bitmaps to the list. If the length ever gets above 20, remove the first item. This will give you some undo buffer and allow you to more easily handle the operation. As for saving to the sd card look here.

~Aedon

Edit 1:

Use this method to create the bitmap of the canvas.

public Bitmap toBitmap(Canvas canvas) {
    Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    canvas.setBitmap(b);
    draw(canvas);
    return b;
}

Sample onToushListener:

new OnTouchListener() {
    public void onTouch(View v, MotionEvent e) {
        switch(e.getAction()) {
            case MotionEvent.ACTION_DOWN: mIsGesturing = true; mCurrentDrawPath.moveTo(...); // Fall through
            case MotionEvent.ACTION_MOVE: // create the draw path the way you are now.
            case MotionEvent.ACTION_UP: mIsGesturing = false; addNewBufferBitmap(toBitmap(canvas)); break;
        }
    }
};

And onDraw(canvas) will look similar to this:

public void onDraw(Canvas canvas) {
    canvas.drawBitmap(getLastBufferBitmap(), 0, 0, null);
    if (mCurrentDrawPath != null) canvas.drawPath(mCurrentDrawPath, mPathPaint);
    if (mIsGesturing) mCanvas = canvas;
}


This code is working in my drawing app..

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

精彩评论

暂无评论...
验证码 换一张
取 消