LoginSignup
37
36

More than 5 years have passed since last update.

VectorDrawableをBitmapに変換する

Last updated at Posted at 2016-03-12

Support Library v23.2.0でVectorDrawableCompatが追加されたことにより、Lollipop未満のバージョンでもVectorアイコンが使えるようになりました。

使い方は簡単。ImageViewは android:srcの代わりに app:srcCompat を使うだけです。TextViewの android:drawableLeft などの場合も、StateListDrawableを作って中にVectorDrawableを指定すれば動きます。

詳しくは以下を参照。

VectorDrawableが直接使えないケース

ただ、GoogleMapのマーカーアイコンなどはまだVectorDrawableを直接指定することはできません。下記のようにvectorアイコンを指定すると落ちます。StateListDrawableを使っても同じです。

new MarkerOptions()
    .position(new LatLng(latitude, longitude))
    .title("タイトル")
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_place_vector)); // コレ
ic_place_vector.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="36dp"
    android:height="36dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#F44336"
        android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z" />
</vector>

Bitmapに変換する

VectorDrawableをBitmapに変換することで対応しました。

new MarkerOptions()
    .position(new LatLng(latitude, longitude))
    .title("タイトル")
    .icon(BitmapDescriptorFactory.fromBitmap(ResourceUtil.getBitmap(context, R.drawable.ic_place_vector))); // コレ
ResourceUtil.java
public class ResourceUtil {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
                vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        vectorDrawable.draw(canvas);
        return bitmap;
    }

    private static Bitmap getBitmap(VectorDrawableCompat vectorDrawable) {
        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
                vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        vectorDrawable.draw(canvas);
        return bitmap;
    }

    public static Bitmap getBitmap(Context context, @DrawableRes int drawableResId) {
        Drawable drawable = ContextCompat.getDrawable(context, drawableResId);
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof VectorDrawableCompat) {
            return getBitmap((VectorDrawableCompat) drawable);
        } else if (drawable instanceof VectorDrawable) {
            return getBitmap((VectorDrawable) drawable);
        } else {
            throw new IllegalArgumentException("Unsupported drawable type");
        }
    }

}

VectorDrawableとVectorDrawableCompatの分岐部分が結構ゴリゴリやってますが、これでLollipop未満もLollipop以上も動きます。

参考 : https://github.com/konifar/droidkaigi2016/pull/349/files

37
36
0

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
37
36