web-dev-qa-db-ja.com

プログラムでサポートベクターに色を付ける

Android Studioバージョン2.1、gradleバージョン2.1.0、誤解を見つけた場合は訂正してください:)

サポートライブラリ23.3.0のサポートベクターについて混乱しています。具体的には、プログラムで画像ボタンに色を付けることです。そのsrcは、ベクトル描画可能であると定義されています。私が言えることから、これはロリポップ以前では不可能です。

変更に関するいくつかの関連記事を読みました: 23.2.0の発表と変更

Androidサポートライブラリ23.3.0以降、サポートベクタードローアブルはapp:srcCompatまたはsetImageResource()を介してのみロードできます。

上記は、ベクトルxmlはsrcCompatまたはsetImageResource()を介してLollipopより前にのみ使用できるため、動的に色付けできないことを意味しますか?

これが私の基本的な画像ボタンです:

_<ImageButton
    Android:id="@+id/nav_header_exit_community_button"
    Android:layout_width="48dp"
    Android:layout_height="48dp"
    Android:layout_alignParentTop="true"
    Android:layout_alignParentRight="true"
    Android:background="@null"/>
_

ロリポップ以上でのみ動作します:

_    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);
_

このロリポップ前のスローを試みると:_Android.content.res.Resources$NotFoundException: File res/drawable/ic_exit_to_app_24dp.xml from drawable resource ID #0x7f0200bf_

ロリポップ以上でも動作します

_    Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageResource(R.drawable.ic_exit_to_app_24dp);
_

これにより、ロリポップ以前でも同じエラーがスローされます。

ただし、指摘されているように_vectorDrawables.useSupportLibrary = true_を削除すると ここではIan Lakeによる 、ビルドツールにロリポップ以前のデバイスのpngを自動生成させる目的でpngはロリポップ以前に色が付いていないので、正方形に戻ります。

また、srcCompatを介してベクトルを指定し、プログラムで取得しようとしましたが、ベクトルがsrc代わりに。

したがって、23.3.0の状況は次のようになります。

  • ロリポップ後:srcおよびsrcCompatはベクトルを受け入れ、プログラムで色付けするためのドローアブルとしてビューから取得できるのはsrcのみです。コード内のベクトルの参照は、getDrawableを使用して可能であり、色を付けることができます。

  • プレロリポップ:srcCompatはベクトルのみを受け入れることができ、色付けのビューからプログラムで取得することはできません。 setImageResourceはベクトルを受け入れることができますが、_vectorDrawables.useSupportLibrary = false_の場合に限り、色付けは機能しません。同様に、コード内のベクトルを参照することは、_vectorDrawables.useSupportLibrary = false_と色付けが機能しない場合を除いて不可能です。

pngを使用したすべてのバージョンでの作業:

_   Drawable bg = ContextCompat.getDrawable(a, R.drawable.ic_nav_exit_community);
   DrawableCompat.setTint(bg, headerTitleColor);
   exitButton.setImageDrawable(bg);
_

補遺:

このテクニックはロリポップ後でも機能しますが、ロリポップ前の他のテクニックと同様に、ドローアブルを取得しますが、色合いはありません。

_    Drawable bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
    DrawableCompat.setTint(bg, headerTitleColor);
    exitButton.setImageDrawable(bg);
_

解決策の種類:

おかげで ジョンの これまでのところ、サポートベクターに色を付けるために私が思いつくことができる唯一の絶対確実な方法は、それにカラーフィルターを設定することです-これは、DrawableCompat.setTint()関数が問題のドローアブルがサポートベクターである場合、私には機能していないようです。これが正当なバグなのか、予想される動作なのか、それとも何か間違ったことをしているだけなのかはわかりません。

これが私が今行っている解決策です:

_    Drawable bg;
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        bg = VectorDrawableCompat.create(a.getResources(), R.drawable.ic_exit_to_app_24dp, null);
        exitButton.setColorFilter(headerTitleColor, PorterDuff.Mode.MULTIPLY);
    }
    else {
        bg = ContextCompat.getDrawable(a, R.drawable.ic_exit_to_app_24dp);
        DrawableCompat.setTint(bg, headerTitleColor);
    }
    exitButton.setImageDrawable(bg);
_
18
Daniel Wilson

まず、VectorDrawableCompat#createを使用する必要があります。Drawableを取得したら、DrawableCompat#wrapを呼び出す必要があります。

このクラスの着色メソッドを介して、さまざまなAPIレベルで着色に使用できるように、ドローアブルをラップする可能性があります。

したがって、コードは次のようになります。

ImageView iv = ....
Drawable d = VectorDrawableCompat.create(getResources(), R.drawable.ic_exit_to_app_24dp, null);
d = DrawableCompat.wrap(d);
DrawableCompat.setTint(d, headerTitleColor);
iv.setImageDrawable(d);
34
pskink

ImageViewの setColorFilter メソッドを使用できます。

imageView.setColorFilter(headerTitleColor, Android.graphics.PorterDuff.Mode.MULTIPLY);

7
John

Kotlinのもう1つの便利なソリューション:

fun Context.drawableWithColor(@DrawableRes drawableRes: Int, @ColorInt color: Int): Drawable? {
    val pic = ContextCompat.getDrawable(this, drawableRes)
    pic?.setColorFilter(color, PorterDuff.Mode.SRC_IN)
    return pic
}

使用は次のように簡単です。

val drawable = context.drawableWithColor(R.drawable.your_awesome_drawable, Color.BLUE)
1
Leo Droidcoder