読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

SupportLibraryのVectorDrawableを使う

Android

ベクター画像のVectorDrawableを使うことで各解像度ごとに画像を用意する必要がなくなります。また画像を拡大してもぼやけることなくキレイに表示できるようになります。

元々はAndroid5.0以降からの対応だったのですが、Support Library 23.2.0から5.0未満にも対応できるようになりました。

使ったことなかったので少し試してみました。

VectorDrawable

公式ドキュメントに記載してあります。

ドローアブルの使用 | Android Developers

Android ではベクター画像は VectorDrawable オブジェクトとして表示されます。

XMLでいろいろ書く感じですが、これを手作業する必要はなくて、Vector Asset Studioっていうのを使用すればSVGファイルから簡単にXMLを生成できます。

Vector Asset Studio

こちらも公式ドキュメントがあります。

Vector Asset Studio | Android Developers

Android Studioからresフォルダを右クリックしてNew -> Vector Assetで起動できます。

UIはシンプルなので使い方はすぐ分かるかと思います。

ローカルのSVGファイルからも生成できますし、matrial iconからも生成できます。

生成するとres/drawableに保存されます。

VectorDrawableを表示する

5.0以降なら普通のリソースと同じようにするだけで使えます。

今回はSupportLibraryを使って5.0未満でもキレイに表示できるようにします。

build.gradle

ここではGradle Pluginが1.5か2.0で書き方が異なるみたいです。

ぼくは1.5のほうで試しました。

android {
    // ...

    // 1.5
    defaultConfig {
        // Stops the Gradle’s automatic rasterization of vectors
        generatedDensities = []
    }

    aaptOptions {
        // Flag that tells aapt to keep the attribute ids
        additionalParameters "--no-version-vectors"
    }
    
    // 2.0以降(未検証)
//    defaultConfig {
//        vectorDrawables.useSupportLibrary = true
//    }

}

dependencies {
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile 'com.android.support:design:23.2.0'
}

generatedDensities は空の配列を設定するこでビルド時にVectorDrawableからPNGファイルを生成するのはやめるように設定します。

これぼくは知らなかったのですが、generatedDensities = ['hdpi']みたいに書くとVectorDrawableからhdpiの解像度用のPNGのみ生成されます。無指定の場合は全解像度のPNGが出力されます。build/generated/res/pngsに出力されます。

additionalParametersについてはすいません、よくわからなかったです。ここにオプションの意味は書いてありましたが、何が変わるのかが分かりませんでした… これがないと実行時エラーになってしまいます。

レイアウトxmlで表示

例としてImageViewに表示してみます。app:srcCompatに該当のVectorDrawableを指定します。

<ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_android_vector" />

これで一応うごくのですが、AndroidStudioから見た時にsrcCompatの箇所が赤線で表示されてしまいます。

気になる場合はImageViewじゃなくて、あえてAppCompatImageViewを指定すると赤線が表示されなくなります。これが正しい対応かは怪しいですが…

<android.support.v7.widget.AppCompatImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/ic_android_vector" />

コードで表示

コードから表示するにはsetImageResourceを使います。

ImageView imageView = (ImageView)findViewById(R.id.image);
imageView.setImageResource(R.drawable.ic_android_vector);

注意

まだ実際のアプリに導入したことはないので何か問題があるかもしれません。

パフォーマンスについては調べてません。

参考