Following is my code. I am able to draw lines but the redo and undo buttons not working. Please can anyone help out.
This is my activity below. Please check the undo and redo methods…
public class Paint_main extends Activity implements OnTouchListener {
static Paint p1;
static Paint p2;
ImageView img;
Bitmap bm;
Float startx;
Float starty;
Float endx;
Float endy;
Button b1;
EditText et;
File file;
File myDir;
private static ToggleButton toggleButton;
private Canvas mCanvas;
private Path mPath;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn_undo = (Button) findViewById(R.id.undoButton);
btn_undo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) { onClickUndo(); }
});
Button btn_redo = (Button) findViewById(R.id.redoButton);
btn_redo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) { onClickRedo(); }
});
bm = Bitmap.createBitmap(getWindowManager().getDefaultDisplay().getWidth(),
getWindowManager().getDefaultDisplay().getHeight(),
Bitmap.Config.ARGB_8888);
img = (ImageView) findViewById(R.id.imageView1);
img.setImageBitmap(bm);
p1 = new Paint();
p1.setAntiAlias(true);
p1.setDither(true);
p1.setStyle(Paint.Style.STROKE);
p1.setStrokeJoin(Paint.Join.ROUND);
p1.setStrokeCap(Paint.Cap.ROUND);
p1.setColor(Color.GREEN);
p1.setStrokeWidth(6);
mCanvas = new Canvas(bm);
mPath = new Path();
// paths.add(mPath);
img.setOnTouchListener(this);
}
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, p1);
// kill this so we don't double draw
// mPath = new Path();
// paths.add(mPath);
paths.add(mPath);
mPath = new Path();
}
public void onClickUndo () {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size()-1));
img.invalidate();
onDraw(mCanvas);
}
}
public void onClickRedo (){
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
img.invalidate();
onDraw(mCanvas);
}
}
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);
img.invalidate();
onDraw(mCanvas);
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
img.invalidate();
onDraw(mCanvas);
break;
case MotionEvent.ACTION_UP:
touch_up();
img.invalidate();
onDraw(mCanvas);
break;
}
return true;
}
protected void onDraw(Canvas canvas) {
//mPath = new Path();
//canvas.drawPath(mPath, mPaint);
for (Path p : paths) { canvas.drawPath(p, p1); }
canvas.drawPath(mPath, p1);
}
}
May be i am calling the above onDraw method incorrectly.
I get it. Problem is:
img.setOnTouchListener(this);This get event, process it and return true, which means this event was handlet.You have 3 options:
1) Set
onTouchListenerto parent view and manually send touch event to childs2) You could determine if user touch images
return true, otherwise return false3) write your own class and override
onTouchEvent(..)methodI recommend 3 option. I rewrite for you:
Don’t forget add your class into layout:
In addition, you should use View instead of ImageView because you don’t use any specific ImageView functions. I rewrite with ImageView for more easier understanding what I mean in third option.