I'm drawing 3 things in my custom view in the onDraw() method: a vector drawable, a simple line and a triangle (made from 4 Points and a Path). This custom view is displayed in a tab.
If I swipe to go to another tab I see that the system calls onDraw(). When I return to the tab holding my custom view the vector drawable and simple line are still visible but the triangle has disappeared. If I now swipe to another tab, onDraw() runs again and back in the tab with the custom view, all items (including the triangle) are now visible. This disappearing/appearing continues to happen as I swipe back and forth. Why is my triangle disappearing?
UPDATE 1 (hacky fix): I've tried experimenting and notice that when I move my triangle Path object creation out of my init() method and put it directly in the onDraw() method - then all works well, nothing disappears. But, I now get the 'Avoid object allocations during draw' warning as I'm creating this object in onDraw();
UPDATE 2 (better fix?): After more experimenting, it's definitely the Path causing this problem. Another solution to this - which doesn't incur the 'Avoid object allocations during draw' warning is: keep Path creation in init() and remove the line of code 'myPath.setFillType(Path.FillType.EVEN_ODD)'. It solves my problem, but I've no idea why.
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Co-ordinates
int width = getWidth();
int halfWidth = width/2;
int left = 0;
int top = 0;
int centreX = left + halfWidth;
int centreY = top + halfWidth;
int baseSize = Math.round((float)(halfWidth * 0.05));
// Vector drawable - always draws fine!
myVectorDrawable.setBounds(left, top, left + width, top + width);
myVectorDrawable.draw(canvas);
// Simple line - always draws fine!
canvas.drawLine(left, top, 20, 20, paint);
// Triangle - sometimes visible, sometimes disappears!
Point myTriangleBottomMiddle = new Point(centreX, centreY);
Point myTriangleBottomLeft = new Point(centreX, centreY + baseSize);
Point myTriangleBottomRight = new Point(centreX, centreY - baseSize);
Point myTriangleTopMiddle = new Point(centreX + halfWidth, centreY);
myPath.moveTo(myTriangleBottomMiddle.x, myTriangleBottomMiddle.y);
myPath.lineTo(myTriangleBottomLeft.x, mTriangleBottomLeft.y);
myPath.lineTo(myTriangleTopMiddle.x, myTriangleTopMiddle.y);
myPath.lineTo(myTriangleBottomRight.x, myTriangleBottomRight.y);
mPath.close();
canvas.drawPath(myPath, myPaint);
}
Below the code where I set up stuff so as not to burden the onDraw() method.
private void init() {
// Vector drawable
myVectorDrawable = r.getDrawable(R.drawable.gauge_dial);
// Triangle path - ** THIS BEING HERE SEEMS TO BE THE PROBLEM **
myPath = new Path();
myPath.setFillType(Path.FillType.EVEN_ODD);
// Triangle Paint
myPaint = new Paint();
myPaint.setColor(r.getColor(R.color.black));
myPaint.setStrokeWidth(2);
myPaint.setAntiAlias(true);
myPaint.setStyle(Paint.Style.FILL);
// Simple line paint
Paint paint = new Paint();
paint.setColor(Color.BLACK);
}
Add a call to reset() on the path.
// Triangle - sometimes visible, sometimes disappears!
Point myTriangleBottomMiddle = new Point(centreX, centreY);
Point myTriangleBottomLeft = new Point(centreX, centreY + baseSize);
Point myTriangleBottomRight = new Point(centreX, centreY - baseSize);
Point myTriangleTopMiddle = new Point(centreX + halfWidth, centreY);
myPath.reset();
myPath.moveTo(myTriangleBottomMiddle.x, myTriangleBottomMiddle.y);
myPath.lineTo(myTriangleBottomLeft.x, mTriangleBottomLeft.y);
myPath.lineTo(myTriangleTopMiddle.x, myTriangleTopMiddle.y);
myPath.lineTo(myTriangleBottomRight.x, myTriangleBottomRight.y);
mPath.close();
canvas.drawPath(myPath, myPaint);
Also, I would recommend putting the vector drawable into a separate view so it's not redrawn everytime you need to animate the triangle (assuming this is going to be an animated guage dial).