Android 4.1.1上的ComposeShader出现问题

Android 4.1.1上的ComposeShader出现问题,android,canvas,gradient,android-4.2-jelly-bean,Android,Canvas,Gradient,Android 4.2 Jelly Bean,我正试图为我的android应用程序实现一个颜色选择器,但在android 4.1.1上遇到了一个奇怪的问题。以下代码不会在Android 4.1.1上创建预期的渐变,但会在2.3.7上创建: Shader fadeInRight = new LinearGradient(0, 0, pWidth, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP); Shader blackToWhite = new LinearGradient(0, 0, 0

我正试图为我的android应用程序实现一个颜色选择器,但在android 4.1.1上遇到了一个奇怪的问题。以下代码不会在Android 4.1.1上创建预期的渐变,但会在2.3.7上创建:

Shader fadeInRight = new LinearGradient(0, 0, pWidth, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP);
Shader blackToWhite = new LinearGradient(0, 0, 0, pHeight, 0xFF000000, 0xFFFFFFFF, Shader.TileMode.CLAMP);
Shader whiteMask = new ComposeShader(blackToWhite, fadeInRight, PorterDuff.Mode.DST_IN);
Shader blackToColor = new LinearGradient(0, 0, pWidth, 0, 0xFF000000, hue, Shader.TileMode.CLAMP);
Shader shader = new ComposeShader(blackToColor, whiteMask, PorterDuff.Mode.SCREEN);
paint.setShader(shader);
...
canvas.drawRect(new Rect(0, 0, pWidth, pHeight), paint);
问题是:

(忽略Android 4.1.1上下面的红色框。我只讨论上面的渐变)

知道出了什么问题吗?我想我的代码中缺少了一些东西,但我不知道是什么

编辑#1: 如果我只是对
设置阴影
使用
whiteMask
,我也会得到两个系统的不同结果:在2.3.7上,我可以看到配置菜单(在弹出窗口后面)的文本在渐变矩形中闪烁。此外,从左上边缘到右下边缘有一个渐变(黑色到白色),但4.1.1中的渐变是从左到右水平移动的因此,
ComposeShader

编辑#2: 我找到了一个更简单的例子来描述这个问题:

Shader shader1 = new LinearGradient(0, 0, 0, pHeight, hue, 0xffffffff, Shader.TileMode.CLAMP);
Shader shader2 = new LinearGradient(0, 0, pWidth, 0, 0xff000000, 0xffffffff, Shader.TileMode.CLAMP);
Shader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.MULTIPLY);

所以,我们有一个从任何颜色到黑色的垂直线性梯度和一个从黑色到白色的水平线性梯度。如果我们将这两层相乘,我们应该得到正确的矩形(如上面的左截图所示)。但在Android 4.1.1上,我只看到shader2的渐变。我还在Gimp中尝试了两层,结果与Android 2.3.7相同。

发现了问题:似乎与硬件加速有关。如上所述,“
ComposeShader
只能包含不同类型的着色器(例如一个BitmapShader和一个LinearGradient,但不能包含BitmapShader的两个实例)”。但是,“如果您的应用程序受到这些缺失功能或限制的影响,您可以通过调用
setLayerType(View.LAYER\u TYPE\u SOFTWARE,null)
关闭应用程序受影响部分的硬件加速。”

我看到,这个方法从SDK 11开始就可用了。我的应用程序支持从SDK 7开始的所有版本,因此我必须检查该方法是否可用:

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

现在一切都好了。

硬件加速是否默认应用?我没有在您提供的链接中找到此信息。不确定,但我想也希望如此:-)还有
ViewCompat.setLayerType(view,view.LAYER\u TYPE\u SOFTWARE,null)支持-v4库中的方法/调用。