I have a custom imageView where i use canvas to draw on top of image. I have issue regarding screen rotation. When screen is rotated i save the path,paint,bitmap then redraw them in onDraw. But afterward i was not able to draw anything on canvas it was disappearing as soon as i draw something new. So i fix that using setBackgroundDrawable to set bitmap.
public void setImageOnImageview(Bitmap canvasBitmap) {
setBackgroundDrawable(new BitmapDrawable( canvasBitmap));
// this.canvasBitmap = canvasBitmap;
}
but now whats happening is previous drawing is going behind the image.
Also it i rotate again then drawing is going away completly.
Below is my code for Custom ImageView
public class DrawingView extends androidx.appcompat.widget.AppCompatImageView {
//drawing path
static CustomPath drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
static int paintColor = 0xFF000000;
//stroke width
private float STROKE_WIDTH = 5f;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private Bitmap currentBitMap;
//eraser mode
private boolean erase = false;
private boolean cc = false;
private int heightB, wieghtB;
//constructor
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
setErase(erase);
}
private void setupDrawing() {
drawPath = new CustomPath();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(STROKE_WIDTH);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//*************************************** View assigned size ****************************************************
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
heightB = h;
wieghtB = w;
drawCanvas = new Canvas(canvasBitmap);
}
public void setPaintColor(int paintColor) {
this.paintColor = paintColor;
setupDrawing();
}
public void setImageOnImageview(Bitmap canvasBitmap) {
setBackgroundDrawable(new BitmapDrawable( canvasBitmap));
// this.canvasBitmap = canvasBitmap;
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
}
public void setErase(boolean isErase) {
erase = isErase;
drawPaint = new Paint();
if (erase) {
int srcColor = 0xFFFFFFFF;
paintColor = 0xFFFFFFFF;
setupDrawing();
PorterDuff.Mode mode = PorterDuff.Mode.CLEAR;
PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(paintColor, mode);
drawPaint.setColorFilter(porterDuffColorFilter);
drawPaint.setColor(paintColor);
drawPaint.setXfermode(new PorterDuffXfermode(mode));
} else {
drawPaint.setXfermode(null);
setupDrawing();
}
}
// ------------ trying to retain canvas on screen rotation ----------
//************************************ draw view *************************************************************
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (cc) {
// canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
//canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.save();
canvas.rotate(90);
canvas.restore();
setVariables(canvasPaint, drawPaint, currentBitMap);
canvas.drawPath(drawPath, drawPaint);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
cc = false;
}
else {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
// setVariables(canvasPaint, drawPaint, currentBitMap);
}
public Paint getDrawPaint() {
return drawPaint;
}
public void setDrawPaint(Paint drawPaint) {
this.drawPaint = drawPaint;
invalidate();
}
public Paint getCanvasPaint() {
return canvasPaint;
}
// public void setCC() {
// cc = true;
// }
public void setCanvasPaint(Paint canvasPaint) {
this.canvasPaint = canvasPaint;
invalidate();
}
public void setVariables(Paint canvasPaint, Paint drawPaint, Bitmap canvasBitmap) {
// this.canvasBitmap = canvasBitmap;
// setImageOnImageview(canvasBitmap);
setImageOnImageview(canvasBitmap);
this.canvasPaint = canvasPaint;
this.drawPaint = drawPaint;
PorterDuff.Mode mode = PorterDuff.Mode.OVERLAY;
drawPaint.setXfermode(new PorterDuffXfermode(mode));
setupDrawing();
// invalidate();
}
public CustomPath getPath() {
return drawPath;
}
public void setDrawPath(CustomPath customPath) {
drawPath = customPath;
}
public Bitmap getCustomBitmap() {
return canvasBitmap;
}
public void setCanvasBitmap(Bitmap bitmap) {
cc = true;
currentBitMap = bitmap;
}
//*************************** respond to touch interaction **************************************************
@Override
public boolean onTouchEvent(MotionEvent event) {
canvasPaint.setColor(paintColor);
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
if (erase) {
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
drawPath.moveTo(touchX, touchY);
} else {
drawPath.lineTo(touchX, touchY);
}
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//*********************************** return current alpha ***********************************************
public int getPaintAlpha() {
return Math.round((float) STROKE_WIDTH / 255 * 100);
}
//************************************** set alpha ******************************************************
public void setPaintAlpha(int newAlpha) {
STROKE_WIDTH = Math.round((float) newAlpha / 100 * 255);
drawPaint.setStrokeWidth(newAlpha);
setupDrawing();
}
}
How do i resolve this ? i could not find any answer.
Edited : I resolved the drawing going behind the image by setting setForeground instead of setBackgroundDrawable.
But still there is the issue of drawing going away if rotate the screen two times in a row.
I want the drawing to stick to the image despite screen rotation. For example If draw something on the middle of the ball then rotate the screen drawing should not reset and should come on middle of the ball not somewhere else.
How do i achieve this ?