0

如何在 canvas 上执行 Undo/Redo 操作。而且我的代码很糟糕,我没有执行这两个操作。在主类中,由于这个原因正在执行绘画,我没有执行撤消重做操作。

public class MainActivity extends Activity implements OnClickListener{

MyView mView;
private Path mPath;
Button btnUndo,btnRedo;
FrameLayout frmLayout;
private Paint       mPaint;
private MaskFilter  mEmboss;
Bitmap  mBitmap;
int bckcolor=0xffffffff;
final Context context = this;

ArrayList<Path> paths = new ArrayList<Path>();
ArrayList<Path> undonePaths = new ArrayList<Path>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mView = new MyView(this);
    setContentView(R.layout.activity_main);

    btnUndo=(Button)findViewById(R.id.Undo);
    btnRedo=(Button)findViewById(R.id.Redo);

    btnUndo.setOnClickListener(this);
    btnRedo.setOnClickListener(this);

    frmLayout=(FrameLayout)findViewById(R.id.frameLayout);
    frmLayout.addView(mView,LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);  

    mPaint = new Paint();
    mPath=new Path();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFF000000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(5);
    new Canvas();       
   paths.add(mPath);

    mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 6, 3.5f);
    new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub


    switch (v.getId()) {

   case R.id.Undo:

       if (paths.size()>0) 
        { 
           undonePaths.add(paths.remove(paths.size()-1));
           mView.invalidate();
           Toast.makeText(getApplicationContext(), "Undo", 1000).show();
         }
        mView.undo();
        break;
   case R.id.Redo:
        mView.redo();
        break;

    default:
        break;
    }
}

public class MyView extends View {

        private float posX = 105;  
        private float posY = 105;  
        Mode mode;
        private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;
        ArrayList<Path> paths = new ArrayList<Path>();
        ArrayList<Path> undonePaths = new ArrayList<Path>();
        BlurMaskFilter blurMaskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.OUTER);
        int screenWidth;
        int screenHeight;

    /**
     */
    public MyView(Context c) 
    {
        super(c);
        mBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.e);
        mBitmap = Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888);            
        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mCanvas.drawColor(0xFFFFFFFF);
        paths.add(mPath);           
    }       

    public void redo() {
        // TODO Auto-generated method stub
        if (undonePaths.size()>0) 
        { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            invalidate();
        } 
        else 
        {

        }

    }

    public void undo() {
        // TODO Auto-generated method stub

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

    @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: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 drawImage (int resourceId)
    {
        Bitmap _scratch = BitmapFactory.decodeResource(getResources(), resourceId);

        mCanvas.drawBitmap(_scratch, 0, 0, null);
    } 

} 

} 
4

4 回答 4

2

像这样更改您的代码....

public MyView(Context context, Object object) 
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(0xFFFFFF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
mCanvas = new Canvas();
mPath = new Path();

mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
selectedcolor=context.getResources().getColor(com.example.videoapp.R.color.red);
}

protected void onDraw(Canvas canvas) 
{
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (Path p : paths)
{
mPaint.setColor(colorsMap.get(p));
canvas.drawPath(p, mPaint);
}

        mPaint.setColor(selectedcolor);
        canvas.drawPath(mPath, mPaint);
 }

在ontouch事件中..

ACTION_DOWN:

undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
    invalidate();

ACTION_MOVE:

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

ACTION_UP:

mPath.lineTo(mX, mY);
paths.add(mPath);
    colorsMap.put(mPath,selectedcolor);
    mPath = new Path();
    mPath.reset();
invalidate();

不要把这个 paths.add(mPath) 放在上下文中并且 oncreate 也......

    public MyView(Context context, Object object) 
    {
     super(context);
    //  paths.add(mPath);   // Dont put this line...
     }

撤消和重做......

    undo.setOnClickListener(new View.OnClickListener() 
    {
public void onClick(View v) 
    {
if(MyView.paths.size()> 0) 
    {
 MyView.undonePaths.add(MyView.paths.remove(MyView.paths.size() - 1));
      mview.invalidate();
}
}
    });

    redo.setOnClickListener(new View.OnClickListener() 
    {
public void onClick(View v) 
    {
  if (MyView.undonePaths.size()>0) 
    { 
       MyView.paths.add(MyView.undonePaths.remove(MyView.undonePaths.size()-1));
       mview.invalidate();
    }
}
});

我希望这段代码对你真的很有用.. 一切顺利

于 2012-12-10T05:54:23.937 回答
0

我尝试了这段代码,它工作得很好......

Here is my code...

// declare the variable colorsMap.     

private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();  

//declare the integer variable selectedcolor

public static int selectedcolor;

 // set the color for integer varible like this code below.....

 public MyView(Context context, Object object) 
 {
  super(context);
  mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
  mCanvas = new Canvas(mBitmap);
  selectedcolor1=context.getResources().getColor(com.example.videoapp.R.color.red);
 } 


// In ONtouchevent

case MotionEvent.ACTION_UP:
paths.add(mPath);
colorsMap.put(mPath,selectedColor); // store the color of mPath


// Before drawing a path, you need to set the paint color:

protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (Path p : paths)
{
    mPaint.setColor(colorsMap.get(p));
    canvas.drawPath(p, mPaint);
}
mPaint.setColor(selectedColor);
canvas.drawPath(mPath, mPaint);
}

我希望它对你非常有用和有帮助。如果你想要三色意味着声明三个整数变量并在 ondraw() 中设置它。

享受朋友......

于 2012-12-07T10:10:01.423 回答
0

@Android 帮助:我在我的代码中解决了这个问题。问题在于,由于在 onTouch 案例中添加了路径,但颜色选择变得混乱,因此将颜色与类中的整数相关联,然后在您引用的任何地方使用该类进行颜色更改。如果您有任何疑问,请告诉我。如果您对已解决的问题不清楚,我可以在这里发布我的代码

于 2013-11-16T01:51:57.187 回答
0

不要放

  paths.add(mPath); 

在 oncreate 和 context 中,放

 paths.add(mPath); 

在鼠标上。

于 2012-12-05T11:33:35.673 回答