web-dev-qa-db-ja.com

GoogleMap BitmapDescriptorを使用したVectorDrawable

GoogleマップBitmapDescriptorに問題がありますMarkerOptions、API 5.0+を使用してVectorDrawableのアイコンを作成中

作成に使用される方法:

_@NonNull
private BitmapDescriptor getBitmapDescriptor(int id) {
    return BitmapDescriptorFactory.fromResource(id);
}
_

id引数にpng drawableが含まれている場合はすべてうまくいきますが、xmlで定義されたVectorDrawableで試してみると、googleMap.addMarker(marker)BitmapDescriptorがnullではない)。

_11-05 10:15:05.213 14536-14536/xxx.xxxxx.app E/AndroidRuntime: FATAL EXCEPTION: main
    Process: xxx.xxxxx.app, PID: 14536
    Java.lang.NullPointerException
        at com.google.a.a.ae.a(Unknown Source)
        at com.google.maps.api.Android.lib6.d.dn.<init>(Unknown Source)
        at com.google.maps.api.Android.lib6.d.dm.a(Unknown Source)
        at com.google.maps.api.Android.lib6.d.ag.<init>(Unknown Source)
        at com.google.maps.api.Android.lib6.d.eu.a(Unknown Source)
        at com.google.Android.gms.maps.internal.j.onTransact(SourceFile:167)
        at Android.os.Binder.transact(Binder.Java:380)
        at com.google.Android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
        at com.google.Android.gms.maps.GoogleMap.addMarker(Unknown Source)
        at xxx.xxxxx.app.ui.details.DetailActivity.lambda$initGoogleMaps$23(DetailActivity.Java:387)
        at xxx.xxxxx.app.ui.details.DetailActivity.access$lambda$10(DetailActivity.Java)
        at xxx.xxxxx.app.ui.details.DetailActivity$$Lambda$13.onMapReady(Unknown Source)
        at com.google.Android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
        at com.google.Android.gms.maps.internal.zzl$zza.onTransact(Unknown Source)
        at Android.os.Binder.transact(Binder.Java:380)
        at com.google.Android.gms.maps.internal.av.a(SourceFile:82)
        at com.google.maps.api.Android.lib6.d.fa.run(Unknown Source)
        at Android.os.Handler.handleCallback(Handler.Java:739)
        at Android.os.Handler.dispatchMessage(Handler.Java:95)
        at Android.os.Looper.loop(Looper.Java:135)
        at Android.app.ActivityThread.main(ActivityThread.Java:5221)
        at Java.lang.reflect.Method.invoke(Native Method)
        at Java.lang.reflect.Method.invoke(Method.Java:372)
        at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:899)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:694)
_

ドロアブルを取得する方法は関係ありません。_BitmapFactory.fromResources_以降の_BitmapDescritpionFactory.fromBitmap_を使用してビットマップを作成しようとしましたが、結果は同じです。これは、ベクトルDrawableでは機能しません。異なるベクトルも試してみましたが、ここではベクトルの複雑さは問題ではないようです。

誰もこのクラッシュを修正する方法を知っていますか?

@編集

問題はBitmapDescriptior自体ではなく、誤ったビットマップを返すVectorDrawableのロードにあるようです。しかし、答えとして提案された解決策はまだ問題ありません。

30
Than

考えられる回避策:

private BitmapDescriptor getBitmapDescriptor(int id) {
    Drawable vectorDrawable = context.getDrawable(id);
    int h = ((int) Utils.convertDpToPixel(42, context));
    int w = ((int) Utils.convertDpToPixel(25, context));
    vectorDrawable.setBounds(0, 0, w, h);
    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bm);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bm);
}
41
Than

バグレポートvaughandroidによる投稿 -ありがとう!)によると、VectorDrawableの使用は当面サポートされません。詳細については、 バグレポートのコメント を参照してください。

Googleマップチームから提案された回避策は次のとおりです。

/**
 * Demonstrates converting a {@link Drawable} to a {@link BitmapDescriptor},
 * for use as a marker icon.
 */
private BitmapDescriptor vectorToBitmap(@DrawableRes int id, @ColorInt int color) {
    Drawable vectorDrawable = ResourcesCompat.getDrawable(getResources(), id, null);
    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());
    DrawableCompat.setTint(vectorDrawable, color);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

このように使用しました:

// Vector drawable resource as a marker icon.
    mMap.addMarker(new MarkerOptions()
            .position(ALICE_SPRINGS)
            .icon(vectorToBitmap(R.drawable.ic_Android, Color.parseColor("#A4C639")))
            .title("Alice Springs"));

ベクトルの色付けはボーナスです

12
lbarbosa

ここに別の参照があります: http://qiita.com/konifar/items/aaff934edbf44e39b04a

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");
    }
}
}
6
TeeTracker

VectorDrawableからBitmapDescriptorに色合いなし

private BitmapDescriptor getBitmapDescriptor(@DrawableRes int id) {
        Drawable vectorDrawable = ResourcesCompat.getDrawable(getResources(), id, null);
        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 BitmapDescriptorFactory.fromBitmap(bitmap);
    }

ありがとう@lbarbosa

4
AndyW

コトリンでも同じ

private fun getBitmapDescriptorFromVector(id: Int, context: Context): BitmapDescriptor {
    var vectorDrawable: Drawable = context.getDrawable(id)
    var h = (24 * getResources().getDisplayMetrics().density).toInt();
    var w = (24 * getResources().getDisplayMetrics().density).toInt();
    vectorDrawable.setBounds(0, 0, w, h)
    var bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
    var canvas = Canvas(bm)
    vectorDrawable.draw(canvas)
    return BitmapDescriptorFactory.fromBitmap(bm)
}

EDIT @ CoolMindあなたは完全に正しい、ありがとう-編集

1
kazimad

コトリン版

private fun getBitmapDescriptor(context: Context, id: Int): BitmapDescriptor? {
    val vectorDrawable: Drawable?
    if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.Lollipop) {
        vectorDrawable = context.getDrawable(id)
    } else {
        vectorDrawable = ContextCompat.getDrawable(context, id)
    }
    if (vectorDrawable != null) {
        val w = vectorDrawable.intrinsicWidth
        val h = vectorDrawable.intrinsicHeight

        vectorDrawable.setBounds(0, 0, w, h)
        val bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        val canvas = Canvas(bm);
        vectorDrawable.draw(canvas);

        return BitmapDescriptorFactory.fromBitmap(bm);
    }
    return null
}
1
Chris Chute