Edited at

Support Vector Drawableのバージョン間差異について

More than 3 years have passed since last update.

Support Library ver23.2 から、support-vector-drawable が追加され Android のlollipop 未満でも Vector 画像が利用できるようになりました。

使い方とその仕組みについては、 @takahirom さんが以下の投稿で詳細に解説してくださっています。

【Android】Support LibraryのVectorDrawableCompatが適応されるまでの仕組み

この記事の内容は、上記投稿のおかげですぐに調べることが出来ました。takahiromさん、ありがとうございます。


ver23.2 と ver23.3 の違い

4/8付の AndroidDevelopers の Google+ の投稿で、このことに触れていました。

関連クラスの diff なども確認したところ、およそ以下のような違いがあります。

No.
処理
v23.2
v23.3

1
app:srcCompat

2
setImageResouce(id)

3
getDrawable(id)

4
lollipop
framework
support


違いその1:Resources から VectorDrawable へのアクセス

takahirom さんの投稿にあるように、AppCompat は内部で getDrawable() を override しており、Resources から VectorDrawable にアクセスすることを可能にしていました。

しかし、ver23.3.0 ではメモリ関連の不具合調査が必要として、その機能は削除されたとのことです。

そのため、例えば以下のような使い方は ver23.2.0 or 23.2.1 では動きますが、 ver23.3.0 では Resouces#NotFoundException が発生するようになっています。

訂正

コメントでの指摘にある通り、MenuItem では AppCompatDrawableManager で getDrawable() しているので、 ver23.3.0 でも VectorDrawable に対応していました。

MenuなどでのVectorDrawable利用

<menu xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
>
<item
android:id="@+id/search"
android:title="@string/menu_search"
android:icon="@drawable/ic_search_vector"
android:orderInCategory="100"
app:showAsAction="always"
/>
</menu>

Resourcesからのアクセス

Drawable drawable = getResources().getDrawable(R.drawable.ic_wallet_vector);


違いその1の差分

実際に ver23.2 と ver23.3 で差分があるのは、getDrawable を override している箇所です。

ver23.2.1

    @Override

public Drawable getDrawable(int id) throws NotFoundException {
Drawable d = super.getDrawable(id);
Context context = mContextRef.get();
if (d != null && context != null) {
AppCompatDrawableManager.get().tintDrawableUsingColorFilter(context, id, d);
}
return d;
}

ver23.3.0

    @Override

public Drawable getDrawable(int id) throws NotFoundException {
final Context context = mContextRef.get();
if (context != null) {
return AppCompatDrawableManager.get().onDrawableLoadedFromResources(context, this, id);
} else {
return super.getDrawable(id);
}
}


違いその2:lollipop での挙動

ver23.2 では、API level 21 以上のときは、framework の VectorDrawable を使うようになっていたのですが、 ver23.3 ではその条件が API level 23 以上に引き上げられています。

そのため、 ver23.3 では lollipop の場合でも xml をパースして VectorDrawable を読み込む方式で処理されることになります。

以下は、VectorDrawableCompat クラスのコメントです。

ver23.2.1

/**

* For API 21 and above, this class is delegating to the framework's {@link VectorDrawable}.
* For API 20 and below, this class lets you create a drawable based on an XML vector graphic.
* ...
*/

ver23.3.0

/**

* For API 23 and above, this class is delegating to the framework's {@link VectorDrawable}.
* For older API version, this class lets you create a drawable based on an XML vector graphic.
* ...
*/