解决Android中不再支持的Canvas.clipPath()问题

时间:2012-01-17 13:46:10

标签: android android-canvas hardware-acceleration

在Android 3.0中,打开硬件加速的设备不再支持clipPath()方法。(有关详细信息,请阅读此article)。

我正在使用画布,我需要绘制圆形图像。关于我该怎么做的任何想法?

*我无法关闭硬件加速,我正在寻找其他解决方案。

已经回答了: Tnx @Malcolm为您的答案。我找到了一个展示this technique的好例子,它基本上是一个面具。

2 个答案:

答案 0 :(得分:41)

具有硬件加速功能的

clipPath仅在API级别18及更高版本中受支持,在需要关闭的级别11到17之间。

您提到的文章包含一条线索:

  

如果您的应用程序受到任何这些缺失的功能或限制的影响,您可以通过调用setLayerType(View.LAYER_TYPE_SOFTWARE, null)来关闭应用程序受影响部分的硬件加速。这样,您仍然可以利用其他地方的硬件加速。有关如何在应用程序的不同级别启用和禁用硬件加速的详细信息,请参阅Controlling Hardware Acceleration

这里的主要想法是禁用应用程序中需要在API级别低于18的设备上使用不受支持的方法的硬件加速。您可以针对特定视图执行此操作,无需转向它完全适用于整个应用程序。

如果您不想关闭硬件加速,那么我建议使用Porter-Duff模式。您可以创建一个带圆圈的位图,然后使用将您的图像剪切为原始内容的模式将图像绘制到画布上。

答案 1 :(得分:27)

API 18 以来,已经重新引入了对{p>} Canvas.clipPath()硬件加速的支持。

解决此问题的最佳方法是仅在从11到17运行API时调用setLayerType(View.LAYER_TYPE_SOFTWARE, null)

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2
        && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    setLayerType(LAYER_TYPE_SOFTWARE, null);
}

我还使用try-catch块围绕clipPath()调用以避免不可预测的应用崩溃:

if (doClip) {
    try {
        canvas.clipPath(clipPath);
    } catch (UnsupportedOperationException e) {
        Log.e(TAG, "clipPath() not supported");
        doClip = false;
    }
}

无论如何,不​​应该在API&gt; = 18上抛出UnsupportedOperationException。

请参阅Unsupported Drawing Operations