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

Ily*_*man 23 android hardware-acceleration android-canvas

从android 3.0 开始,硬件加速开启的设备不再支持clipPath()方法.(阅读本文了解更多详情).

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

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

回答:Tnx @Malcolm的答案.我发现了一个展示这种技术的好例子,它基本上是一个面具.

Mal*_*olm 41

clipPath 硬件加速仅在API级别18及更高级别受支持,在11级到17级的API级别上需要关闭.

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

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

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

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


ara*_*aks 27

Canvas.clipPath()API 18以来,已经重新引入了硬件加速支持.

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

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

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

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

无论如何,不​​应该在API> = 18上抛出UnsupportedOperationException.

请参阅不支持的绘图操作