Android 5.0からSVG準拠のdrawableが書けるようになりました
こんにちは、Androidチームの中川@Nkznです。
Android Studio 0.8.14のリリースノートを見ていて知ったのですが、LollipopのAPI Level 21では<vector>
などのdrawable系タグが拡充されたのですね。
名前的にベクターイメージが書けそうですが、実際何ができるのだろうと思って調べてみました。
Vector images are represented in Android as VectorDrawable objects. For more information about the pathData syntax, see the SVG Path reference.
<vector>
の中に書く<path>
タグのpathData
の記法が、SVG準拠のようです。サンプルコードがこちら。
<path android:fillColor="#8fff" android:pathData="M20.5,9.5 c-1.955,0,-3.83,1.268,-4.5,3 c-0.67,-1.732,-2.547,-3,-4.5,-3 C8.957,9.5,7,11.432,7,14 c0,3.53,3.793,6.257,9,11.5 c5.207,-5.242,9,-7.97,9,-11.5 C25,11.432,23.043,9.5,20.5,9.5z" />
なるほどとてもSVGでした。
何が嬉しいのか
http://developer.android.com/design/style/iconography.html
SVGをはじめとしたベクターイメージの強みの1つとしてよく云われるのは、拡縮しても綺麗さが変わらないという点です。
Androidでは(最近ではiOSも)対象端末の解像度ごとに別々の大きさの画像を用意するのがそれなりに手間です。また、同じアイコンでもアプリ内で使う場所(左上用、ボタン用、見出し用など)が変われば、それぞれに別々のサイズを用意しなければいけません。
SVGで画像リソースを作成できるようになれば、1種類のリソースで様々なサイズの要求に応えることができるようになりますので、嬉しい事になりそうです。
余談:公式Material Designアイコン
そういえば先日、Googleがマテリアルデザイン向けのシステムアイコンをリリースしたことが話題になっていました。
このニュースを見た時には「SVGが用意されていても、どうせWebでしか使えない」と考えていたのですが、Lollipop以降のバージョンでは<vector>
によってSVG(っぽいもの)が利用できますので、転用の可能性が広がります。
試してみた
実際にSVGはどのように表示されるのでしょうか。前述のマテリアルデザインアイコンから下記のic_add_to_photos_48px.svgを拝借して、表示してみたいと思います。
SVGから変換(手作業)
- ic_add_to_photos_48px.svg
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"> <path d="M0 0h48v48h-48z" fill="none"/> <path d="M8 12h-4v28c0 2.21 1.79 4 4 4h28v-4h-28v-28zm32-8h-24c-2.21 0-4 1.79-4 4v24c0 2.21 1.79 4 4 4h24c2.21 0 4-1.79 4-4v-24c0-2.21-1.79-4-4-4zm-2 18h-8v8h-4v-8h-8v-4h8v-8h4v8h8v4z"/> </svg>
- drawable/ic_add_to_photos_48px.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="256dp" android:width="256dp" android:viewportWidth="48" android:viewportHeight="48"> <path android:fillColor="#000000" android:pathData="M8 12h-4v28c0 2.21 1.79 4 4 4h28v-4h-28v-28zm32-8h-24c-2.21 0-4 1.79-4 4v24c0 2.21 1.79 4 4 4h24c2.21 0 4-1.79 4-4v-24c0-2.21-1.79-4-4-4zm-2 18h-8v8h-4v-8h-8v-4h8v-8h4v8h8v4z"/> </vector>
それっぽく似たような雰囲気にしてみました。width, height周りは適当です。
この時点で、レイアウトエディタがプレビューをしてくれるようになりました。
数値を適当に弄ってみるとちゃんと反映されます。
画面に組み込む
一度drawableリソースとして取り込んでしまえば、使い方としてはいつもの<shape>
と似たようなものです。
- activity_main.xml
<!-- 略 --> <FrameLayout android:layout_width="24dp" android:layout_height="24dp" android:background="@drawable/ic_add_to_photos_48px" /> <!-- 略 -->
上記のようなFrameLayout
を何サイズか並べてみたものがこちらになります。
一手間かければSVGアイコンがAndroidでも使えるようになったことがお分かりいただけたかと思います。
まとめ/雑感
ということで、長らくAndroidアプリ開発者を悩ませてきた画面の断片化問題が1つ解決するのではないかという期待が持てる機能を紹介しました。
最後に少しだけネガティブなことを言うと、パフォーマンスとか大丈夫なのかなーと思ったりはしました。それから、
@nkzn それだ!というか、ここまでやっておいてなぜsvgをそのままつかえるようにしてくれないんでしょうかね?
— ウズキアオバ (@uzuki_aoba) 2014年10月30日
これは思いました。わざわざ直すのは面倒です。drawableフォルダにSVGファイルそのまま置かせてもらえると一番嬉しいのですが・・・しばらくは動的にSVGをVectorDrawableに変換するような手法を使うのが現実的でしょうか。
まあ、日本でLollipopが十分に普及するまではまだしばらくかかると思いますので、周辺環境が整うのを見守りたいと思います。(support-v7あたりに取り込まれないかなと)
それでは今回はこのへんで。
宣伝
ウォーターセル株式会社では、農業生産者に嬉しい情報の扱い方を一緒に考えてくれるWebフロントエンドエンジニア、Railsエンジニア、Androidアプリエンジニアを探しています。
興味のある方は、是非一度新潟まで遊びに来てみてください。