在自定义视图 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);

此外,我建议将矢量可绘制对象放入单独的视图中,这样就不会在每次需要为三角形设置动画时重新绘制它(假设这将是一个动画刻度盘)。