Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7938243
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T22:45:06+00:00 2026-06-03T22:45:06+00:00

I am using a customized version of FingerPaint for Android with some other features,

  • 0

I am using a customized version of FingerPaint for Android with some other features, like inserting images and moving them. I decided to implement an Undo&Redo, since it will make life just easier. In order to implement it, I finally decided to use a Stack where I push the Drawing Cache of the view, and from where I push the content every time I want to go back to a previous state. So, using the FingerPaint as a basis, I have the following:

private void touch_up() {
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, mPaint);
    // I enable the set drawing cache...       
    myView.setDrawingCacheEnabled(true);
    // ... and I add the cache to the stack
    undoStack.add(myView.getDrawingCache());
    indexOfUndoRedo++;
    // kill this so we don't double draw
    mPath.reset();
} 

The stack is being updated only after the touch up at the moment, since I am still figuring out how to solve this. When I want to apply redo, I do the following:

private void undo() {
    myView = new MyView(getActivity());
    myView.setBackgroundDrawable(new BitmapDrawable(undoStack.get(indexOfUndoRedo)));
    indexOfUndoRedo--;
    myView.invalidate();
} 

So far, the application shows the original state of the screen with no change. I also tried to paint it with a white background in order to reset it, but this approach is also not working.

Any idea or suggestion on how to fix this? I would be really thankful 🙂

Regards

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T22:45:08+00:00Added an answer on June 3, 2026 at 10:45 pm

    Try below code Draw View:

    package com.draw;
    import java.util.ArrayList;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Path;
    
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.ImageView;
    
    public class DrawView extends View implements OnTouchListener {
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint       mPaint;   
        private ArrayList<Path> paths = new ArrayList<Path>();
        private ArrayList<Path> undonePaths = new ArrayList<Path>(); 
    
        private Bitmap im;
        public DrawView(Context context) 
        {
            super(context);
            setFocusable(true);
            setFocusableInTouchMode(true);      
            this.setOnTouchListener(this);
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(0xFFFFFFFF);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(6);
            mCanvas = new Canvas();
            mPath = new Path();
            paths.add(mPath);
    
            im=BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_launcher);
    
    
        }               
            @Override
            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                super.onSizeChanged(w, h, oldw, oldh);
            }
    
            @Override
            protected void onDraw(Canvas canvas) {            
    
                for (Path p : paths){
                    canvas.drawPath(p, 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);
                // commit the path to our offscreen
                mCanvas.drawPath(mPath, mPaint);
                // kill this so we don't double draw            
                mPath = new Path();
                paths.add(mPath);
            }
    
            public void onClickUndo () { 
                if (paths.size()>0) 
                { 
                   undonePaths.add(paths.remove(paths.size()-1));
                   invalidate();
                 }
                else
                {
    
                }
                 //toast the user 
            }
    
            public void onClickRedo (){
               if (undonePaths.size()>0) 
               { 
                   paths.add(undonePaths.remove(undonePaths.size()-1)); 
                   invalidate();
               } 
               else 
               {
    
               }
                 //toast the user 
            }
    
        @Override
        public boolean onTouch(View arg0, 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;
        }
    }
    

    and Draw Activity layout code below:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
     <FrameLayout android:id="@+id/main_frame"
         android:layout_width="fill_parent" android:layout_height="250dp">
    
     </FrameLayout>
            <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Redo" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Undo" />
    
    </LinearLayout>
    

    and Draw Activity Class below code:

    package com.draw;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.ImageButton;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.Toast;
    
    public class Draw extends Activity {
         ImageView iv1;
        @Override   
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final DrawView drawView = new DrawView(this);
            setContentView(R.layout.main);
            FrameLayout frm_layout=(FrameLayout) findViewById(R.id.main_frame);
            frm_layout.addView(drawView);
            Button btn_undo=(Button) findViewById(R.id.button1);
            btn_undo.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    drawView.onClickUndo();
                }
            });
    
            Button btn_redo=(Button) findViewById(R.id.button2);
            btn_redo.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    drawView.onClickRedo();
                }
            });
        }
    
    }
    

    This is sample paint app with undo and redo operations in android,it work’s perfectly for me!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I build a customized search web page using some other search engine. like. For
We are developing a customized installer using Wix and Wpf. We have developed some
I'm using the jQuery UI Autocomplete plugin (version 1.8), and I'd like to customize
We are developing customized installer using visual studio 2008 installer project. The requirement which
I am using map kit and showing customized annotation view. One is carImage and
When a class is customized, by using its outlet , you cant access its
I'm using asp.net mvc 3, My problem is I need to use the customized
Our team is currently using some ported code from an old architecture to a
I'm using Bing Maps, and with CSS I'm styling the HTML-elements to get customized
I am using a customised version of search-theme-form.tpl When I use the search box,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.