下一课是红三角的视图:
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]);
}
}
当我使用Canvas.drawPath方法时,它工作正常。但是,如果我改为Canvas.drawVertices,它什么也没画。我已经检查了Bug in Canvas.drawVertices? (with repro code and logcat)和Method drawVertices() didn't drawing anything on Android Canvas中的内容,但结果与我的情况相同。
我在AndroVM(v 4.1.1)中使用VirtualBox(v 4.1.22)进行测试。它可能是模拟器吗?
有什么想法吗?
答案 0 :(得分:9)
简答:
禁用硬件加速,你会没事的!
答案很长:
我遇到了完全相同的问题。在我的自定义View代码中,我调用了Canvas.drawVertices(),如下所示:
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, mTriVerts.length, mTriVerts, 0, null, 0, mTriangleColors, 0, null, 0, 0, mTriPaint);
这与许多设备上的预期完全一样,但在我的4.x测试设备上,我试图绘制的三角形消失了,并且logcat中没有迹象表明原因。
在S.O.找不到解决方案后我开始挖掘并偶然发现以下令人震惊的解决方案:如果启用了硬件加速,包括对Canvas.drawVertices()
的任何调用,一堆标准内容将无效,并且默认情况下在所有设备上启用硬件加速支持Android 4.x及更高版本。
问题和良好的解决方案概述in the official android docs。要在此总结一下,只需将其放在不受支持的呼叫之前的行上:
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
这是View
级别的,遗憾的是,无法在目前已设置为软件模式的视图上重新启用硬件加速,但是阅读它感觉到的文档可能是将来的选择。如果您觉得您的代码需要硬件加速,只需避免使用这些调用,或者在视图中单独收集不兼容的代码,并对其进行分析以确定您实际上通过这种方式获得了某些东西。
重要编辑:
仅在Android API 11级及更高版本上支持setLayerType()
调用,这意味着您必须在版本检查中将对此函数的调用包装起来,以便它可以在以下版本中运行:
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
现在你应该全力以赴!
PS:我希望这个答案及时到达你的身上!