15

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 for だけを使用するとsetShader、両方のシステムで異なる結果が得られます。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);

したがって、任意の色から黒への垂直方向の線形グラデーションと、黒から白への水平方向の線形グラデーションしかありません。これら 2 つのレイヤーを乗算すると、正しい長方形が得られるはずです (上の左のスクリーンショットのように)。しかし、Android 4.1.1 では、shader2 のグラデーションしか表示されません。2つのレイヤーを使用してGimpでもこれを試しましたが、結果はAndroid 2.3.7と同じでした。

4

1 に答える 1

20

問題が見つかりました:ハードウェアアクセラレーションに関係しているようです。here で説明されているように、 'ComposeShader異なるタイプのシェーダーのみを含めることができます (たとえば、BitmapShader と LinearGradient を含めることができますが、BitmapShader の 2 つのインスタンスを含めることはできません)。ただし、「アプリケーションがこれらの欠落している機能または制限のいずれかの影響を受ける場合は、setLayerType(View.LAYER_TYPE_SOFTWARE, null). '

このメソッドは SDK 11 以降で使用できることがわかりました。私のアプリは SDK 7 以降のすべてのバージョンをサポートしているため、メソッドが使用可能かどうかを確認する必要があります。

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

今は大丈夫です。

于 2012-09-16T12:04:06.407 に答える