Reputation: 271
How can I perform the Undo/Redo operation on canvas . And my code is blow and i am not performing the these two operation .In the main class paint is performing by this reason am not perform the undo redo operation.
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);
}
}
}
Upvotes: 0
Views: 3790
Reputation: 5126
@Android Help: I solved this problem in my code. The problem is that as the paths are being added in onTouch cases but color selection is getting messed up so associate color with an integer in a class and then use that class for color changes where ever you are referencing. Let me know if you have any doubt. I can post my code here if not clear to you with solved problem
Upvotes: 0
Reputation: 119
Change your code like this....
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);
}
In ontouch event..
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();
Dont put this paths.add(mPath) in context and oncreate also...
public MyView(Context context, Object object)
{
super(context);
// paths.add(mPath); // Dont put this line...
}
Undo and Redo....
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();
}
}
});
I hope this code is really veryuseful to u.. all the best
Upvotes: 2
Reputation: 119
I try this code it was working perfectly.....
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);
}
I hope it was very useful and helpful to u. if u want to threecolor means declare three integer variables and set this in ondraw().
ENJOY FRIENDS................
Upvotes: 0
Reputation: 119
Dont put
paths.add(mPath);
in oncreate and context, put
paths.add(mPath);
in mouse up.
Upvotes: 0