web-dev-qa-db-ja.com

AndroidのGoogleマップのカスタムマーカーとベクトルアセットアイコン

ベクター資産ファイルでマップマーカーアイコンを達成するにはどうすればよいですか?プログラムでGoogleがこのように表示する方法:

map

更新:

map.addMarker(new MarkerOptions()
    .position(latLng)
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.your_vector_asset))
    .title(title);

これは、ベクターアセットを扱う場合には機能しません。質問する主な理由。上記のコードのエラー:

Java.lang.IllegalArgumentException:画像のデコードに失敗しました。提供される画像はビットマップである必要があります。

47
Shuddh

私はまったく同じ要件を探していましたが、この質問に最初は満足していましたが、@ Shuddhと同じように、与えられた答えには満足していませんでした。

ストーリーを短くするために、この要件に次のコードを使用しています。

private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes  int vectorDrawableResourceId) {
    Drawable background = ContextCompat.getDrawable(context, R.drawable.ic_map_pin_filled_blue_48dp);
    background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
    Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId);
    vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20);
    Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    background.draw(canvas);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

および使用例:

.icon(bitmapDescriptorFromVector(this, R.drawable.ic_car_white_24dp));

注:ベクトルに別の境界を使用することをお勧めします。ベクトルのサイズは24dpで、背景として48dpのpng画像(青い部分、ベクトルにもなります)を使用しました。

更新:要求されたとおりにスクリーンショットを追加します。

Screenshot for end result

18
Sid Morad

次の方法を使用できます。

private BitmapDescriptor bitmapDescriptorFromVector(Context context, int vectorResId) {
        Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorResId);
        vectorDrawable.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
        Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vectorDrawable.draw(canvas);
        return BitmapDescriptorFactory.fromBitmap(bitmap);
}

したがって、コードは次のようになります。

map.addMarker(new MarkerOptions()
                .position(latLng)
                .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset))
                .title(title);

編集
Kotlinでは次のようになります。

private fun bitmapDescriptorFromVector(context: Context, vectorResId: Int): BitmapDescriptor? {
        return ContextCompat.getDrawable(context, vectorResId)?.run {
            setBounds(0, 0, intrinsicWidth, intrinsicHeight)
            val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
            draw(Canvas(bitmap))
            BitmapDescriptorFactory.fromBitmap(bitmap)
        }
    }
69
Leo Droidcoder

ゲームに少し遅れる可能性がありますが、これはGoogleマップv2でうまく機能します。

public static BitmapDescriptor getBitmapFromVector(@NonNull Context context,
                                                   @DrawableRes int vectorResourceId,
                                                   @ColorInt int tintColor) {

    Drawable vectorDrawable = ResourcesCompat.getDrawable(
            context.getResources(), vectorResourceId, null);
    if (vectorDrawable == null) {
        Log.e(TAG, "Requested vector resource was not found");
        return BitmapDescriptorFactory.defaultMarker();
    }
    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, tintColor);
    vectorDrawable.draw(canvas);
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

初期化:

locationMarkerIcon = LayoutUtils.getBitmapFromVector(ctx, R.drawable.ic_location_marker,
                ContextCompat.getColor(ctx, R.color.marker_color));

使用法:

googleMap.addMarker(MarkerOptions().icon(getMarkerIcon()).position(latLng));

注:getMarkerIcon()は、初期化されたnull以外のlocationMarkerIconメンバー変数を返すだけです。

スクリーンショット:

enter image description here

2
prerak

ベクターリソースをビットマップオブジェクトに変換し、BitmapDescriptorFactory.fromBitmap(bitmap)を使用

   Bitmap bitmap = getBitmapFromVectorDrawable(getContext(),R.drawable.ic_pin);
   BitmapDescriptor descriptor =BitmapDescriptorFactory.fromBitmap(bitmap);
   MarkerOptions markerOptions = new MarkerOptions();
   markerOptions.icon(descriptor);

ビットマップコンバーター:

 public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
        Drawable drawable =  AppCompatResources.getDrawable(context, drawableId)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
            drawable = (DrawableCompat.wrap(drawable)).mutate();
        }

        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }
0
Shahab Saalami

ここでコトリンを探している人があなたのための方法である場合:

  private fun  bitmapDescriptorFromVector(context: Context, vectorResId:Int):BitmapDescriptor {
            var vectorDrawable = ContextCompat.getDrawable(context, vectorResId);
            vectorDrawable!!.setBounds(0, 0, vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight());
            var bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            var canvas =  Canvas(bitmap);
            vectorDrawable.draw(canvas);
            return BitmapDescriptorFactory.fromBitmap(bitmap);
}

上記のメソッドは、ベクトルアイコンをビットマップ記述子に変換します

map.addMarker(new MarkerOptions()
                .position(latLng)
                .icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset))
                .title(title)

そして、これはあなたのマップのマーカーを設定するためのものです。彼の答えからレオ・ドロイドコーダーに感謝します私はそれをkotlinに変換しました

0
M.Yogeshwaran