问题ComposeShader在Android 4.1.1问题、ComposeShader、Android

2023-09-05 05:43:26 作者:执她手

我只是想实现一个拾色器为我的Andr​​oid应用程序,并遇到了一个奇怪的问题在Android 4.1.1。下面code没有在Android 4.1.1创建预期的梯度,但它确实在2.3.7:

I'm just trying to implement a color picker for my android application, and ran into a strange issue on Android 4.1.1. The following code does not create the expected gradients on Android 4.1.1, but it does on 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);

这里的问题:

Here's the problem:

(忽略在Android 4.1.1冲下面框。我只是说说上面的梯度)的

任何想法有什么不对?我觉得有东西在我的code失踪,但我没有什么想法,有什么。

Any Idea what's wrong? I think there is something missing in my code, but I don't have any idea, what.

编辑#1: 如果我只是用 whiteMask setShader ,我也得到不同的结果,这两个系统:在2.3.7,我可以看到配置菜单中通过梯度矩形闪亮的文字(这是弹出后面)。此外,还设有从左上角边缘到右下边缘(黑至白)的梯度,但在4.1.1梯度变为水平地从左到右。 因此,它似乎是一个问题 ComposeShader

EDIT #1: If I just use whiteMask for setShader, I also get different results for both systems: On the 2.3.7 I can see the text of the configuration menu (which is behind the popup) shining through the gradient rectangle. Furthermore there is a gradient from the upper left edge to the lower right edge (black to white), but the gradient on the 4.1.1 goes horizontally from left to right. So it seems to be a problem with ComposeShader

编辑#2: 我发现了一个更简单的例子来说明问题:

EDIT #2: I found a more simpler example to describe the problem:

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。

So, we have just a vertical linear gradient from any color to black and a horizontal linear gradient from black to white. If we multiply these two layers, we should get the correct rectangle (as in the left screenshot above). But on Android 4.1.1 I see only the gradient of shader2. I also tried this in Gimp with two layers and the result was the same as on Android 2.3.7.

推荐答案

发现问题:看来,它做的硬件加速。由于此处描述的 ComposeShader 仅可包含不同类型的着色器(一个BitmapShader和一个的LinearGradient为实例,但BitmapShader不是两个实例)的'。但是,如果您的应用程序受到任何这些缺失的功能或限制,您可以通过调用关闭硬件加速您的应用程序只是受影响的部分 setLayerType(View.LAYER_TYPE_SOFTWARE,空) 。的

Found the problem: Seems that it has to do with the hardware acceleration. As described here 'ComposeShader can only contain shaders of different types (a BitmapShader and a LinearGradient for instance, but not two instances of BitmapShader)'. But, 'If your application is affected by any of these missing features or limitations, you can turn off hardware acceleration for just the affected portion of your application by calling setLayerType(View.LAYER_TYPE_SOFTWARE, null).'

我看到,这种方法是可用,因为SDK 11.我的应用程序支持所有版本的开头SDK 7,所以我要检查,如果方法是可行的:

I saw, that this method is available since SDK 11. My App supports all versions starting with SDK 7, so I have to check if the method is available:

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

现在一切都很好。