前の記事の続きです。
適当に設定を書き換えているだけでは埒が明かないので、一から歴史を勉強してきました。
そもそもVector Drawableリソースを使えるようになったのはAPI21 Android5.0 Lollipopからで、
それよりも前のバージョンでDrawableリソースを扱うために、Support Library23.2からで対応された。Support Library23.2以上を利用することでAPI19 Android4.4KitKat~API11 Android3.0 HoneycombでDrawableリソースを扱うことができるようになった。ということらしいです。
android-developers.googleblog.com
Android Studio 3.4で新規にプロジェクトを作った場合、特に意識することなく適用されています。たぶん。
↓build.gradle
// Gradle Plugin 2.0+ android { defaultConfig { vectorDrawables.useSupportLibrary = true } } dependencies { compile 'com.android.support:appcompat-v7:23.2.0' //最低バージョン }
実際にVector Drawableリソースを使うときにはSupport Library向けにコードを書く必要があります。
ImageView及びそのサブクラスでVector Drawableリソースを使用する場合、android:src属性ではなくapp:srcCompat属性で指定しなければいけません。
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_add" />
ImageView以外でVector Drawableリソースを使いたい場合…これについては、公式情報を見つけることができませんでした。
が、幸いQiitaにて素晴らしい記事を発見。
TextViewの場合は、直接VectorDrawableを指定すると落ちます。 そのため、StateListDrawableを作成してその中でVectorDrawableを指定してあげる必要があります。
なるほど、ということでVector Drawableに対応するState List Drawableを作成します。
State List Drawableについてはよく知りませんが、Stateに応じてDrawableを変えるセレクタらしいです。
で、ActivityのLayoutファイル内でDrawableリソースを使用する時には@drawable/ic_hoge_stateを指定してやります。
ImageView以外ではうまく動作しないSupport LibraryのVector Drawableの後方互換機能が、stateファイルがあるとうまく動作するようになるのかなと・・・想像です。
Android Developers Blog Support Library23.2の記事の中ほどになぜか取り消されている部分を読んでみると
However, AppCompat does support loading vector drawables when they are referenced in another drawable container such as a StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable, and RotateDrawable. By using this indirection, you can use vector drawables in cases such as TextView’s android:drawableLeft attribute, which wouldn’t normally be able to support vector drawables.
StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable, and Rotate Drawableを使うとTextViewのandroid:drawableLeft属性でもVector Drawableがサポートされる…みたいなことが書いてある?
ただ、私の環境ではまだ設定が足りませんでした。
Top ActivityまたはApplicationにてstaticでAppCompatDelegate.setCompatVectorFromResourcesEnabled(true);を実行します。
public class MainActivity extends AppCompatActivity { static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } ... }
Support Library 23.4から使える設定みたいです。
意味はよく分かりません。
medium.comの記事"Android: Crash when using vector Drawables on Pre Lollipop."によると
For AppCompat users, we’ve added an opt-in API to re-enable support Vector Drawables from resources (the behavior found in 23.2) via AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) - keep in mind that this still can cause issues with memory usage and problems updating Configuration instances, hence why it is disabled by default.
(23.3で) 23.2のバグを修正するオプトインを追加したけど、メモリ使用量に関する問題を持っているので(23.4では)デフォルトで無効になっている…みたいなことが書いてある?
上記すべての設定を行うことで無事SeekBarにVector Drawableリソースを適用することができました。
- build.gradleでvectorDrawables.useSupportLibrary = true
- compile 'com.android.support:appcompat-v7:23.4.0' //以上を使う
- 全てのVector Drawableに対してState List Drawableを作成する。
- AppCompatActvtyにstaticでAppCompatDelegate.setCompatVectorFromResourcesEnabled(true);を追加する
ただし、メモリ使用量の問題があるとの事なので、minSDKがAPI19 Android4.4 KitKat 以下なら素直にPNGを使う方が無難というのが、個人的な結論です。
Stateファイル作るのも面倒ですし。
以上
丸一日つぶれたぁぁぁぁあああ(# ゚Д゚)