Takuji->find;

株式会社はてなでアプリケーションエンジニアやってます、技術的な記事を書いているつもり

VectorDrawable support libraryを使うにはAppCompat widgetを使わないといけない

こんにちは、takuji31です。

昨日リリースされたSupport Library 23.2.0で早速ハマりました。

TL;DR

VectorDrawableCompatを使って古いAndroidでもVector Drawableを表示したい時に、AppCompatActivity(あるいはAppCompatDelegate)を使っていない場合はAppCompatImageViewの子クラス(AppCompatImageView、AppCompatImageButton、FloationgActionButton)を明示的に使う必要がある。

経緯

今開発しているアプリに早速使うことになり、同僚のid:cockscombに導入してもらって「Support Library最高!」みたいな話をしていただけですけど、マージしたらログイン画面にあるアプリのロゴが表示されなくなりました。

どうせまたSupport LibraryのバグでVector変換無効になってないんじゃね?と思ってandroid:srcに設定したらKitKat以下で「そんなDrawableのタグしらねーよ」って怒られる始末。

Androidのissue見ても「srcCompatに設定したVector表示されねーんだけどー????」みたいなものは発見できず。

とにかく意味が分からないという気持ちでした。

AppCompatがVectorDrawableCompatを読み込むまで

見出しの通り、VectorDrawableCompatでVectorを読むにはAppCompatが必要で、これはドキュメントにも書いてあります。

逆に言えばそれ以上はちゃんと明言されていません。

そこで調べてみたところ、具体的には以下の通りになっていました。

  • VectorDrawableCompatを読み込んでいる実体はAppCompatDrawableManager
  • AppCompatDrawableManagerをAppCompatImageHelperが使ってapp:srcCompatやsetImageResourceメソッドに設定されるVectorDrawableCompatを読み込む
  • AppCompatImageHelperはAppCompatImageViewが生成して使っている

ログイン画面のコード眺めてたらAccountAuthenticatorActivityを使っていて、AccountAuthenticatorActivityは(Android framework内のActivityなので)AppCompatActivityではなくActivityを直接継承しています。

そのため、ImageViewはもちろんImageViewのままで、AppCompatImageViewは使われていない。

解決策

明示的にAppCompatImageViewやその子クラスをレイアウトファイルに指定してやるとちゃんと表示できました。

使ってみた感想

今回のSupport Libraryのアップデートはめちゃくちゃ変わった!という感じではないけど、とにかく便利な機能が増えた印象。

個人的によさげと思っているのBottomSheetBehaviorとVectorDrawableCompatで、BottomSheetBehaviorは公式でサポートされたことでライブラリーの依存がいくつか減りそう(実際減った)だし、VectorDrawableCompatはもう画像リソースはVectorでいいのよ、って言われている感じ。