Android 如何在画布上执行撤消重做而不丢失以前的颜色

Android 如何在画布上执行撤消重做而不丢失以前的颜色,android,Android,我没有在此代码中执行撤消/重做操作。当am使用阵列列表删除位置时,它将不起作用,并且在从颜色选择器更改油漆颜色的过程中,先前的图形颜色也已更改。 我不了解如何对此执行撤消/重做。 所以请帮忙 //这是主课 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView (mView = new MyView(this)); mPaint = new P

我没有在此代码中执行撤消/重做操作。当am使用阵列列表删除位置时,它将不起作用,并且在从颜色选择器更改油漆颜色的过程中,先前的图形颜色也已更改。 我不了解如何对此执行撤消/重做。 所以请帮忙

//这是主课

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (mView = new MyView(this));

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);

mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
                               0.4f, 6, 3.5f);

mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}

//MyView类是

public class MyView extends View {

private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;  
private Bitmap  mBitmap;
private Canvas  mCanvas;
private Path    mPath;
private Paint   mBitmapPaint;
ArrayList<Path> paths = new ArrayList<Path>();
ArrayList<Path> undonePaths = new ArrayList<Path>();
public MyView(Context c) 
{
super(c);

mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// mCanvas.setBackgroundResource(0xFFFFFFFF);
mCanvas.drawColor (0xFFFFFFFF);
paths.add(mPath);
}
public MyView (Context c, int color)
   {
   super(c);

     mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
     mCanvas = new Canvas(mBitmap);
     mPath = new Path();
     mBitmapPaint = new Paint(Paint.DITHER_FLAG);
     mCanvas.drawColor (color);
     paths.add(mPath);
  }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) 
 {
     super.onSizeChanged(w, h, oldw, oldh);
 }

 @Override protected void onDraw(Canvas canvas) 
  {
     canvas.drawColor(0xFF000000);

     canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
     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);  
       mCanvas.drawPath(mPath, mPaint);
       paths.add(mPath);
       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;
     }

    public void clear ()
     {
         Paint p = new Paint();
         p.setAntiAlias(true);
         p.setDither(true);
         p.setColor(0xFFFFFFFF);
         mCanvas.drawPaint (p);
      } 

   public void drawImage (int resourceId)
    {
         Bitmap _scratch = BitmapFactory.decodeResource(getResources(), resourceId);
         mCanvas.drawBitmap(_scratch, 0, 0, null);
    } 
    public void undo() {
        // TODO Auto-generated method stub
        mCanvas.drawCircle(posX, posY, 100, mPaint);
        Toast.makeText(getApplicationContext(), "Hello", 1000).show();
        if (paths.size()>0) 
        { 
           undonePaths.add(paths.remove(paths.size()-1));
           mView.invalidate();
           Toast.makeText(getApplicationContext(), "Undo", 1000).show();
         }
        else
        {
            Toast.makeText(getApplicationContext(), "Not", 1000).show();
        }
    }
          public void redo() {
        // TODO Auto-generated method stub
        if (undonePaths.size()>0) 
        { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            invalidate();
        } 
        else 
        {

        }

    }
   public void saveAsJpg (File f)
     {
        String fname = f.getAbsolutePath ();
        FileOutputStream fos = null;
        try {
        fos = new FileOutputStream (f);
        mBitmap.compress (CompressFormat.JPEG, 95, fos);                 
       } catch (Throwable ex) {
      ex.printStackTrace ();
       }      
     } // end saveAsJpg

   } // end MyView

   } // end class FingerPaint
公共类MyView扩展了视图{
专用静态最终浮动最小值=0.25f;
专用静态最终浮动最大值=0.75f;
私有位图mBitmap;
私人帆布mCanvas;
专用路径mPath;
私人油漆;
ArrayList路径=新的ArrayList();
ArrayList undonePaths=新建ArrayList();
公共MyView(上下文c)
{
超级(c);
mBitmap=Bitmap.createBitmap(320480,Bitmap.Config.ARGB_8888);
mCanvas=新画布(mBitmap);
mPath=新路径();
mBitmapPaint=新油漆(油漆抖动标志);
//mCanvas.setBackgroundResource(0xFFFFFFFF);
mCanvas.drawColor(0xFFFFFFFF);
路径。添加(mPath);
}
公共MyView(上下文c,int颜色)
{
超级(c);
mBitmap=Bitmap.createBitmap(320480,Bitmap.Config.ARGB_8888);
mCanvas=新画布(mBitmap);
mPath=新路径();
mBitmapPaint=新油漆(油漆抖动标志);
mCanvas.drawColor(彩色);
路径。添加(mPath);
}
@覆盖IZECHANGE上的受保护无效(int w、int h、int oldw、int oldh)
{
super.onSizeChanged(w,h,oldw,oldh);
}
@覆盖受保护的void onDraw(画布)
{
canvas.drawColor(0xFF000000);
drawBitmap(mBitmap,0,0,mbitMapPoint);
用于(路径p:路径)
{
画布绘制路径(p,mPaint);
}
}
私人浮动mX,我的;
专用静态最终浮动接触公差=4;
专用无效触摸启动(浮动x、浮动y){
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y){
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差){
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补(){
mPath.lineTo(mX,mY);
mCanvas.drawPath(mPath,mPaint);
路径。添加(mPath);
mPath.reset();
}
@重写公共布尔onTouchEvent(MotionEvent事件){
float x=event.getX();
float y=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
触摸启动(x,y);
使无效();
打破
case MotionEvent.ACTION\u移动:
触摸移动(x,y);
使无效();
打破
case MotionEvent.ACTION\u UP:
润色;
使无效();
打破
}
返回true;
}
公共空间清除()
{
油漆p=新油漆();
p、 setAntiAlias(真);
p、 设置抖动(真);
p、 设置颜色(0xFFFFFF);
mCanvas.drawPaint(p);
} 
public-void-drawImage(int-resourceId)
{
位图_scratch=BitmapFactory.decodeResource(getResources(),resourceId);
drawBitmap(_scratch,0,0,null);
} 
公共作废撤消(){
//TODO自动生成的方法存根
mCanvas.drawCircle(posX,posY,100,mPaint);
Toast.makeText(getApplicationContext(),“Hello”,1000).show();
if(path.size()>0)
{ 
undonePaths.add(path.remove(path.size()-1));
mView.invalidate();
Toast.makeText(getApplicationContext(),“Undo”,1000).show();
}
其他的
{
makeText(getApplicationContext(),“Not”,1000).show();
}
}
公共无效重做(){
//TODO自动生成的方法存根
如果(撤消路径大小()>0)
{ 
add(undonePaths.remove(undonePaths.size()-1));
使无效();
} 
其他的
{
}
}
公共void saveAsJpg(文件f)
{
字符串fname=f.getAbsolutePath();
FileOutputStream=null;
试一试{
fos=新文件输出流(f);
mBitmap.compress(CompressFormat.JPEG,95,fos);
}捕获(可丢弃的ex){
例如printStackTrace();
}      
}//结束saveAsJpg
}//结束MyView
}//结束类FingerPaint
这是一段有效的代码。我在自己的应用程序上测试了它,效果非常好。
可能对你有帮助。请评论一下。
公共类主扩展活动实现OnColorChangedListener{
//公共静态int selectedColor=Color.BLACK;
公共静态数组列表mMaindialog;
//私人ArrayList undonePaths;
//公共int-selectedcolor;
私有静态最终字符串COLOR\u PREFERENCE\u KEY=“COLOR”;
私有框架布局相对论;
静态字符串sdpath、位置;
布尔i;
//实例变量
私有位图mBitmap=null;
位图;
私人油漆mPaint、mBitmapPaint、mPaint1;
私人MyView mView;
ImageView-idd;
//专用路径mPath;
int slll=Color.BLACK;
位图映射=ListView5.bMap;
私人按钮ClearPaint、Colorpaint;
幽灵数据库gost;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
idd=(ImageView)findViewById(R.id.imageView1);
relativelayout=(FrameLayout)findViewById(R.id.FrameLayout);
DisplayMetrics metrics=getBaseContext().getResources()
.getDisplayMetrics();
int w=度量值。宽度像素;
int h=metrics.heightPixels;
系统输出打印项次(“宽度”+w);
this working code .I test it on my own app and it is working very good.
May be it help u.Please comment on it.
            public class Main extends Activity implements OnColorChangedListener {
            //public static int selectedColor = Color.BLACK;
            public static ArrayList<Path> mMaindialog;
            // private ArrayList<Path> undonePaths;
            // public int selectedcolor;
            private static final String COLOR_PREFERENCE_KEY = "color";
            private FrameLayout relativelayout;
            static String sdpath,location;
            Boolean i;
            // Instance variables
            private Bitmap mBitmap=null;
            Bitmap bitmap;
            private Paint mPaint, mBitmapPaint, mPaint1;
            private MyView mView;
            ImageView idd;
            // private Path mPath;
            int slll = Color.BLACK;
            Bitmap map=ListView5.bMap;
            private Button ClearPaint, Colorpaint;
            Ghostdatabase gost;

            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                 idd=(ImageView)findViewById(R.id.imageView1);
                relativelayout = (FrameLayout) findViewById(R.id.frameLayout);

                DisplayMetrics metrics = getBaseContext().getResources()
                        .getDisplayMetrics();
                int w = metrics.widthPixels;
                int h = metrics.heightPixels;

                System.out.println(" width " + w);
                System.out.println(" height " + h);



                mView = new MyView(this, w, h);
                mView.setDrawingCacheEnabled(true);

                mPaint = new Paint();
                mPaint.setAntiAlias(true);
                mPaint.setDither(true);
                mPaint.setColor(Color.BLACK);
                mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setStrokeJoin(Paint.Join.ROUND);
                mPaint.setStrokeCap(Paint.Cap.ROUND);
                mPaint.setStrokeWidth(4);

                ClearPaint = (Button) findViewById(R.id.ne);
                ClearPaint.setOnClickListener(new OnClickListener() {

                    public void onClick(View v) {
                        // mBitmap.eraseColor(Color.TRANSPARENT);
                        // mPath.reset();
                        // mView.invalidate();

                        mView.onClickUndo();

                    }
                });
                Button save22 = (Button) findViewById(R.id.save);
                save22.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        File cacheDir;
                        Toast.makeText(Main.this, "Photo", 500).show();
                        Bitmap icon;
                        relativelayout.setDrawingCacheEnabled(true);

                        icon = Bitmap.createBitmap(relativelayout.getDrawingCache());
                        Bitmap bitmap = icon;
                        relativelayout.setDrawingCacheEnabled(false);
                        // File mFile1 = Environment.getExternalStorageDirectory();
                        Date d = new Date();
                        String fileName = d.getTime() + "mg1.jpg";

                        File storagePath = (Environment.getExternalStorageDirectory());
                        File dest = new File(storagePath + "/CityAppImages");

                        if (!dest.exists()) {
                            dest.mkdirs();

                        }

                        File mFile2 = new File(dest, fileName);
                        sdpath = mFile2.getAbsolutePath();

                        Log.d("qqqqqqqqqqqqqqqqqqqqqqq", "zzzzzzzz" + sdpath);
                        try {
                            FileOutputStream outStream;

                            outStream = new FileOutputStream(mFile2);

                            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);

                            outStream.flush();

                            outStream.close();
                            Toast.makeText(Main.this, "Photo Saved Sucessfully", 500)
                                    .show();
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {

                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            Toast.makeText(Main.this, "Photo Not Saved Sucessfully",
                                    500).show();
                        }

                        gost = new Ghostdatabase(Main.this);
                        gost.open();

                        gost.insertTitle(sdpath);
                    }
                });

                Button view = (Button) findViewById(R.id.listtt);
                view.setOnClickListener(new OnClickListener() {

                    public void onClick(View v) {

                        Intent ii = new Intent(Main.this, ListView5.class);
                        startActivity(ii);

                    }
                });

                Button Colorpaint = (Button) findViewById(R.id.Color);
                Colorpaint.setOnClickListener(new OnClickListener() {

                    public void onClick(View v) {
                        int color = PreferenceManager.getDefaultSharedPreferences(
                                Main.this).getInt(COLOR_PREFERENCE_KEY, Color.WHITE);
                        // int _color = R.color.red;
                        new ColorPickerDialog(v.getContext(),
                                new OnColorChangedListener() {

                                    public void colorChanged(int color) {
                                        mPaint.setColor(color);

                                        slll = color;

                                        Log.i("TAG", "mpaint one" + mPaint);
                                    }
                                }, mPaint.getColor()).show();
                        Log.i("TAG", "mpaint two" + mPaint);
                    }
                });
                relativelayout.addView(mView);
            }



            // //////////******************* Pinting view
            // *******************///////////////////

            public class MyView extends View implements OnTouchListener {
                private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();
                private ArrayList<Path> mMaindialog = new ArrayList<Path>();
                private ArrayList<Path> undonePaths = new ArrayList<Path>();
                int colorPicked = slll;
                // Paint mPaint1;

                private Canvas mCanvas;
                private Path mPath;

                public MyView(Context c, int w, int h) {
                    super(c);
                    if(GlobalVariable.impath==1)
                    {
                        Log.d("","111111"+GlobalVariable.impath);
                        System.out.println(GlobalVariable.impath);
                        Intent ii = getIntent();
                         location = ii.getStringExtra("IMAGE");
                        // bitmap.recycle();
                         Log.d("","location"+location);
                         bitmap = BitmapFactory.decodeFile(location);
                         mBitmap = Bitmap.createScaledBitmap(bitmap,300, 300,false);
                         Log.d("hhhhhhhhhhhhhhhssssssss","mBitmap"+mBitmap);
                         //mBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
                        // idd.setImageBitmap(mBitmap);
                        Log.d("hhhhhhhhhhhhhhhssssssss","GlobalVariable.impath"+GlobalVariable.impath);
                    }
                    else if(GlobalVariable.impath==2){
                        //bitmap.recycle();
                        Log.d("","22222222222222222222222"+GlobalVariable.impath);
                        bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.base);
                        mBitmap = Bitmap.createScaledBitmap(bitmap,100, 100, false);
                        //mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                        Log.d("hhhhhhhhhhhhhhhssssssss1111111","mBitmap"+mBitmap);
                    }



        //          
                    mCanvas = new Canvas(mBitmap);
                    mPath = new Path();

                }

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

                }

                @Override
                protected void onDraw(Canvas canvas) {

                    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

                    for (Path p : mMaindialog) {
                        mPaint.setColor(colorsMap.get(p));
                        canvas.drawPath(p, mPaint);
                    }
                    mPaint.setColor(slll);
                    canvas.drawPath(mPath, mPaint);
                }

                // //////************touching evants for painting**************///////
                private float mX, mY;
                private static final float TOUCH_TOLERANCE = 0;

                private void touch_start(float x, float y) {
                    mPath.reset();
                    mPath.moveTo(x, y);
                    mX = x;
                    mY = y;
                    undonePaths.clear();
                }

                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();
                    mPath.reset();
                    mMaindialog.add(mPath);
                }

                @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();
                        undonePaths.clear();
                        mPath.reset();
                        mPath.moveTo(x, y);
                        mX = x;
                        mY = y;
                        invalidate();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        // touch_move(x, y);
                        // invalidate();
                        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;
                        }
                        invalidate();
                        break;
                    case MotionEvent.ACTION_UP:
                        // touch_up();
                        // invalidate();
                        mPath.lineTo(mX, mY);
                        mMaindialog.add(mPath);
                        colorsMap.put(mPath, slll);
                        mPath = new Path();
                        mPath.reset();
                        invalidate();
                        break;
                    }
                    return true;
                } // end of touch events for image

                private Paint createPen(int colorPicked) {
                    // TODO Auto-generated method stub
                    mPaint1 = new Paint();
                    mPaint1.setColor(colorPicked);
                    mPaint1.setAntiAlias(true);
                    mPaint1.setDither(true);
                    mPaint1.setStyle(Paint.Style.STROKE);
                    mPaint1.setStrokeJoin(Paint.Join.ROUND);
                    mPaint1.setStrokeCap(Paint.Cap.ROUND);
                    // mPaint1.setStrokeWidth(3);
                    return mPaint1;
                }

                public void onClickRedo() {
                    if (undonePaths.size() > 0) {
                        mMaindialog.add(undonePaths.remove(undonePaths.size() - 1));
                        mView.invalidate();

                    } else {

                    }
                    // toast the user
                }

                public void onClickUndo() {
                    if (mMaindialog.size() > 0) {
                        undonePaths.add(mView.mMaindialog.remove(mView.mMaindialog
                                .size() - 1));
                        mView.invalidate();
                    }

                    else {

                    }
                }

                @Override
                public boolean onTouch(View arg0, MotionEvent arg1) {
                    // TODO Auto-generated method stub
                    return false;
                }
            }// end MyView

            @Override
            public void colorChanged(int color) {
                // TODO Auto-generated method stub
                PreferenceManager.getDefaultSharedPreferences(this).edit()
                        .putInt(COLOR_PREFERENCE_KEY, color).commit();
                slll = color;
            }



        }