0

I am making a drawing app and it has layers. Each time I draw a line it disappears. The process is like this :

  • Draw a line with path and add it to path ArrayList once TOUCH_UP happens (I lift my finger)
  • invalidate is called and then canvas draws all paths stored in the arraylist

Instead of such behavior my path disappears the moment it is drawn and canvas is blank. Methods :

(path,layer1,layer2,layer3 are all ArrayList of Path type)

// constructor where path arraylist is pointing to currently used layer arraylist (all contain path types)
public ArtView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        setupDrawing();
        layer = 1;
        layer1 = new ArrayList<>();
        layer2 = new ArrayList<>();
        layer3 = new ArrayList<>();
        path = layer1;
        undo = new ArrayList<>();
    }

// onDraw is called each time to update canvas with each change
@Override
    protected void onDraw(Canvas canvas) {
        canvas.save();

// load a picture from galery if under is true, make a new bitmap if false
        if (loadedBitmap != null) {
            canvas.drawBitmap(loadedBitmap, 0, 0, paintLine);
        } else {
            canvas.drawBitmap(bitmap, 0, 0, canvasPaint);
        }

// for each layer arraylist draw all their paths on canvas
        for (Path path : layer1) {
            canvas.drawPath(path, paintLine);
        }
        for (Path path : layer2) {
            canvas.drawPath(path, paintLine);
        }
        for (Path path : layer3) {
            canvas.drawPath(path, paintLine);
        }
        canvas.restore();
    }

// touch method that handles drawing
@Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                path.add(mPath); // add currently created path to arraylist to be painted in onDraw
                mPath.reset();
                break;
            default:
                return false;
        }
        invalidate(); // call onDraw and update changes
        return true;
    }

// set up method called when starting this activity (from MainActivity class)
public void setupDrawing() {
        mPath = new Path();
        paintLine = new Paint();
        paintLine.setAntiAlias(true);
        paintLine.setDither(true);
        paintLine.setStrokeJoin(Paint.Join.ROUND);
        paintLine.setStyle(Paint.Style.STROKE);
        paintLine.setColor(paintColor);
        paintLine.setStrokeWidth(1);
        paintLine.setStrokeCap(Paint.Cap.ROUND);
        paintLine.setXfermode(null);
        paintLine.setAlpha(255);
        canvasPaint = new Paint(Paint.DITHER_FLAG);
        lastBrushSize = paintLine.getStrokeWidth();
    }

One more problem is that whenever I draw the first line when starting the app, it never shows the line that is being traced. Only once I finish drawing it is shows up then disappears. The next one I make is visible nicely as I trace it , it also disappears once its done.

Any tips on how to make all the lines remain on canvas and how to make my first line being visible while it is being drawn ?

  • layer1, layer2, layer3 are never filled?.. – Alberto Sinigaglia Sep 01 '21 at 19:45
  • Path is a reference that points to one of the three depending which layer is used at the time. I have a method that changes to which of the three the path will point when layer button is pressed. Whenever the ACTION_UP happens (drawing event ends) this line executes: path.add(mPath);. It adds currently drawn mPath to the path reference which actually just stores each drawing in the layer1(as currently used) array list. I tested all three layers and all of them do store paths whenever they are drawn. Not sure exactly why they disappear from the canvas though, right after they are drawn. – Grim Reaper Sep 01 '21 at 22:25
  • Maybe you have some other component been drawn on top? – Alberto Sinigaglia Sep 01 '21 at 22:34
  • I found a way to make drawn lines appear and stay but it breaks my layer/undo/redo functionality. If I add this line : drawCanvas.drawPath(mPath, paintLine); in TOUCH_UP block. But that makes every line being drawn straight away instead of being stored in layers arrays where I can then make layers and undo/redo work. The first line is still invisible and appears only after I finish drawing it , while others appear right away as I draw them. Quite weird... – Grim Reaper Sep 02 '21 at 08:59
  • what is supposed to be `invalidate()` in your code? – Alberto Sinigaglia Sep 02 '21 at 10:24
  • I would suggest to take a look at this https://stackoverflow.com/questions/3343912/custom-ondraw-method-not-called – Alberto Sinigaglia Sep 02 '21 at 10:26
  • invalidate() causes onDraw() to be called . It is in charge of drawing everything on canvas. I have seen the question but it does not have a solution since my views and onDraw method are called properly. – Grim Reaper Sep 02 '21 at 21:56
  • maybe you are drawing elements the same color as the background?.. – Alberto Sinigaglia Sep 03 '21 at 07:07

0 Answers0