0

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.

before rotaion

after rotation

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 ?

RR_Pradhan
  • 78
  • 12
  • One of the easiest solution is to fix orientation to portrait. – Danish Oct 27 '21 at 07:18
  • That would be easy but i am not allowed to do something like that. I found one solution https://stackoverflow.com/questions/42986817/redraw-multiple-paths-at-same-positions-from-previous-layout-orientation , but some part of the image is cutting off. – RR_Pradhan Oct 27 '21 at 07:22

0 Answers0