LoginSignup
50
52

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-04-12

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.
 * ...
 */
50
52
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
52