web-dev-qa-db-ja.com

Android:DrawableCompatを使用した色合い

Android APIレベル21よりも前に画像に色を付けようとしています。

<Android:tint="@color/red"/>

ただし、ImageViewのコードを使用してこれを行う方法はわかりません。

Drawable iconDrawable = this.mContext.getResources().getDrawable(R.drawable.somedrawable);
DrawableCompat.setTint(iconDrawable, this.mContext.getResources().getColor(R.color.red));
imageView.setImageDrawable(iconDrawable);

私はTintModeを設定しようとしましたが、これは変わらないようです。 v4互換性クラスDrawableCompatを誤って使用していますか?

48
Hippopatimus

クロスプラットフォームに色を付ける最も簡単な方法(ColorStateListが必要ない場合)は次のとおりです。

drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);

フィルターを適用する前にDrawableを変更することを忘れないでください。

43
BladeCoder

他のドロウアブルに影響を与えずにDrawableCompatの色付けを使用する必要がある場合は、mutate()を使用して次のようにします。

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
wrappedDrawable = wrappedDrawable.mutate();
DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.white));

次のように簡略化できます。

Drawable drawable = getResources().getDrawable(R.drawable.some_drawable);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), getResources().getColor(R.color.white));
120
Renan Ferrari

以前は、DrawableCompatでは色付けがサポートされていませんでした。サポートライブラリ22.1から開始できますが、次のようにする必要があります。

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));
53
Simon K. Gerges

ここでの回答は、Lollipopデバイス以前(SupportLib 23.4.0)では機能しませんが、API 17以降で機能する回避策を投稿しました: https://stackoverflow.com/a/37434219/ 2170109

次のコードがテストされ、API 17、19、21、22、23、N Preview 3で動作しています:

    // https://stackoverflow.com/a/30928051/2170109
    Drawable drawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.vector));
    image.setImageDrawable(drawable);

    /*
     * need to use the filter | https://stackoverflow.com/a/30880522/2170109
     * (even if compat should use it for pre-API21-devices | https://stackoverflow.com/a/27812472/2170109)
     */
    int color = ContextCompat.getColor(context, R.color.yourcolor);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        DrawableCompat.setTint(drawable, color);

    } else {
        drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
29
hardysim

DrawableCompatのソースコードを見ると、バージョン<21 メソッドは何もしない であることがわかります。

DrawableCompatのアイデアは、実際にその機能を提供するのではなく、単に古いバージョンでクラッシュしないように思われます。

6
Michael Smith

サポートライブラリ22.1を使用すると、DrawableCompatを使用してドロウアブルに色を付けることができます。

DrawableCompat.wrap(Drawable)およびsetTint()、setTintList()、およびsetTintMode()は機能します。複数の色をサポートするためだけに、個別のドロウアブルを作成および維持する必要はありません!

3
bugraoral

誰かに時間を節約できるかもしれないので、ここで私のソリューションを共有します。

ソースドロアブルとして使用されるベクトルドロアブルを持つImageViewがありました(実際には、サポートベクトルドロアブル from Android Support Library 23.3)でした。最初に次のようにラップしました:

mImageView.setImageDrawable(DrawableCompat.wrap(mImageView.getDrawable()));

そしてその後、私はそれのように色合いを適用しようとしました:

_DrawableCompat.setTint(
    mImageView.getDrawable(),
    getResources().getColor(R.color.main_color)
);
_

運がありません。

元のドロアブルと同様に、ラップされたドロアブルでもmutate()を呼び出そうとしました-まだ運がありません。 mImageViewで呼び出されたinvalidate()がトリックを行いました。

2
aga