Canvas.drawVertices(...)什么都没画

GYL*_*YLZ 5 api android android-canvas

下一个类是红色三角形的视图:

public class FreeStyleViewII extends View {

private final Paint paint = new Paint();
private final int[] colors = new int[] {
        Color.RED,
        Color.RED,
        Color.RED,
        0xFF000000, 0xFF000000, 0xFF000000
};
private final float[] verts = new float[] {
    1f/2f * 200f, 1f/4f * 200f,
    1f/4f * 200f, 3f/4f * 200f,
    3f/4f * 200f, 3f/4f * 200f
};
private final Path path = new Path();
{
    path.moveTo(1/2 * 200, 1/4 * 200);
    path.lineTo(1/4 * 200, 3/4 * 200);
    path.lineTo(3/4 * 200, 3/4 * 200);
    path.lineTo(1/2 * 200, 1/4 * 200);
}

private final RectF bounds = new RectF();

    public FreeStyleViewII(Context context) {
        super(context);
    }

    public FreeStyleViewII(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public FreeStyleViewII(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.clipRect(bounds);
        canvas.drawRGB(0, 0, 0);

        paint.setStyle(Style.FILL);
        paint.setColor(Color.RED);

        // HERE. WHY DRAWVERTICES DOESN'T WORK BUT DRAWPATH DOES?... 
        canvas.drawVertices(Canvas.VertexMode.TRIANGLES, verts.length, verts, 0, null, 0, colors, 0, null, 0, 0, paint);
        // canvas.drawPath(path, paint);

        paint.setStyle(Style.STROKE);
        paint.setColor(Color.LTGRAY);
        canvas.drawLine(0, bounds.bottom / 2, bounds.right, bounds.bottom / 2, paint);
        canvas.drawLine(bounds.right / 2, 0, bounds.right / 2, bounds.bottom, paint);

        // Delay
    try {  
        Thread.sleep(30);  
    } catch (InterruptedException e) { }

        invalidate();

    }

@Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
    bounds.set(1, 1, w - 1, h - 1);
    System.out.println(bounds.left + " " + bounds.top + " " + bounds.right + " " + bounds.bottom);

    verts[0] = bounds.left + ((bounds.right - bounds.left) * (1f / 2f));
    verts[1] = bounds.top + ((bounds.bottom - bounds.top)  * (1f / 4f));
    System.out.println(" Point: X ----> " + verts[0] + " | Y ----> " + verts[1]);

    verts[2] = bounds.left + ((bounds.right - bounds.left) * (1f / 4f));
    verts[3] = bounds.top + ((bounds.bottom - bounds.top)  * (3f / 4f));
    System.out.println(" Point: X ----> " + verts[2] + " | Y ----> " + verts[3]);

    verts[4] = bounds.left + ((bounds.right - bounds.left) * (3f / 4f));
    verts[5] = bounds.top + ((bounds.bottom - bounds.top)  * (3f / 4f));
    System.out.println(" Point: X ----> " + verts[4] + " | Y ----> " + verts[5]);

    path.reset();

    path.moveTo(verts[0], verts[1]);
    path.lineTo(verts[2], verts[3]);
    path.lineTo(verts[4], verts[5]);
    path.lineTo(verts[0], verts[1]);

}
}
Run Code Online (Sandbox Code Playgroud)

当我使用Canvas.drawPath方法时,它工作正常.但是,如果我改为Canvas.drawVertices,它什么也没画.我已经检查过Canvas.drawVerticesBug的内容了吗?(使用repro 代码和logcat)方法drawVertices()没有在Android Canvas上绘制任何东西,但结果在我的情况下是相同的.

我在VirtualBox(v 4.1.22)中使用AndroVM(v 4.1.1 )进行测试.它可能是模拟器吗?

任何的想法?

Len*_*and 9

简短回答:

禁用硬件加速,你会没事的!

答案很长:

我有同样的问题.在我的自定义View代码中,我调用了Canvas.drawVertices(),如下所示:

canvas.drawVertices(Canvas.VertexMode.TRIANGLES, mTriVerts.length, mTriVerts, 0, null, 0, mTriangleColors, 0, null, 0, 0, mTriPaint);
Run Code Online (Sandbox Code Playgroud)

这与许多设备上的预期完全一样,但在我的4.x测试设备上,我试图绘制的三角形消失了,并且logcat中没有迹象表明原因.

在没有找到SO的解决方案后,我开始挖掘并偶然发现以下令人震惊的解决方案:如果启用硬件加速,包括任何调用Canvas.drawVertices(),一堆标准内容将无效,并且默认情况下硬件加速已打开支持Android 4.x及更高版本的设备.

官方的android文档中概述问题和一个很好的解决方案.在这里总结一下,只需将其置于不受支持的呼叫之前的行上:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Run Code Online (Sandbox Code Playgroud)

这是在View水平上,遗憾的是不可能在截至目前已设置为软件模式的视图上重新启用硬件加速,但是阅读它感觉到的文档可能是未来的选项.如果您觉得您的代码需要硬件加速,只需避免使用调用,或者在视图中单独收集不兼容的代码,并对其进行分析以确定您实际上是通过这种方式获得某些东西.

重要编辑:

setLayerType()调用仅在Android API 11级及更高版本上受支持,这意味着您必须在版本检查中包含对此函数的调用,以使其在早期版本上运行,如下所示:

if (android.os.Build.VERSION.SDK_INT >= 11) {
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
Run Code Online (Sandbox Code Playgroud)

现在你应该全力以赴!

PS:我希望这个答案及时到达你!