在自定义视图 onDraw() 中绘制的项目不断消失
Item drawn in Custom view onDraw() keeps disappearing
我在我的自定义视图中使用 onDraw() 方法绘制了 3 个东西:一个矢量可绘制对象、一条简单的线和一个三角形(由 4 个点和一条路径组成)。此自定义视图显示在选项卡中。
如果我滑动转到另一个选项卡,我会看到系统调用 onDraw()。当我 return 到包含我的自定义视图的选项卡时,可绘制的矢量和简单的线仍然可见,但三角形消失了。如果我现在滑动到另一个选项卡,onDraw() 会再次运行并返回带有自定义视图的选项卡,所有项目(包括三角形)现在都可见。当我来回滑动时,这个 disappearing/appearing 继续发生。为什么我的三角形消失了?
更新 1(hacky 修复):
我尝试过实验并注意到,当我将我的三角形 Path 对象创建移出我的 init() 方法并将其直接放在 onDraw() 方法中时 - 然后一切正常,没有任何东西消失。但是,当我在 onDraw();
中创建这个对象时,我现在收到 'Avoid object allocations during draw' 警告
更新 2(更好的修复?):
经过更多的实验,这绝对是导致这个问题的路径。另一种解决方案 - 不会引发 'Avoid object allocations during draw' 警告:在 init() 中保留路径创建并删除代码行 'myPath.setFillType(Path.FillType.EVEN_ODD)'。它解决了我的问题,但我不知道为什么。
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);
}
在我设置内容的代码下方,以免增加 onDraw() 方法的负担。
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);
}
在路径上添加对 reset() 的调用。
// 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);
此外,我建议将矢量可绘制对象放入单独的视图中,这样就不会在每次需要为三角形设置动画时重新绘制它(假设这将是一个动画刻度盘)。
我在我的自定义视图中使用 onDraw() 方法绘制了 3 个东西:一个矢量可绘制对象、一条简单的线和一个三角形(由 4 个点和一条路径组成)。此自定义视图显示在选项卡中。
如果我滑动转到另一个选项卡,我会看到系统调用 onDraw()。当我 return 到包含我的自定义视图的选项卡时,可绘制的矢量和简单的线仍然可见,但三角形消失了。如果我现在滑动到另一个选项卡,onDraw() 会再次运行并返回带有自定义视图的选项卡,所有项目(包括三角形)现在都可见。当我来回滑动时,这个 disappearing/appearing 继续发生。为什么我的三角形消失了?
更新 1(hacky 修复): 我尝试过实验并注意到,当我将我的三角形 Path 对象创建移出我的 init() 方法并将其直接放在 onDraw() 方法中时 - 然后一切正常,没有任何东西消失。但是,当我在 onDraw();
中创建这个对象时,我现在收到 'Avoid object allocations during draw' 警告更新 2(更好的修复?): 经过更多的实验,这绝对是导致这个问题的路径。另一种解决方案 - 不会引发 'Avoid object allocations during draw' 警告:在 init() 中保留路径创建并删除代码行 'myPath.setFillType(Path.FillType.EVEN_ODD)'。它解决了我的问题,但我不知道为什么。
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);
}
在我设置内容的代码下方,以免增加 onDraw() 方法的负担。
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);
}
在路径上添加对 reset() 的调用。
// 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);
此外,我建议将矢量可绘制对象放入单独的视图中,这样就不会在每次需要为三角形设置动画时重新绘制它(假设这将是一个动画刻度盘)。