Пользовательский маркер в Google Maps в android с иконкой вектора
Как мы можем достичь значка маркера карты с файлом векторного ресурса, способ, которым Google показывает это так, программно:
![map]()
Обновление:
map.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_vector_asset))
.title(title);
это не работает при работе с векторными активами. Основная причина - задать вопрос. Ошибка с приведенным выше кодом:
java.lang.IllegalArgumentException: Не удалось декодировать изображение. Предоставленное изображение должно быть растровым.
Ответы
Ответ 1
Я искал точно такое же требование, и, увидев этот вопрос, я сначала был счастлив, но так же, как @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));
Примечание: вы можете захотеть использовать разные границы для ваших векторов, мои векторы были размером 24 dp, и я использовал изображение png 48dp (синяя часть, которая тоже может быть вектором) в качестве фона.
ОБНОВЛЕНИЕ: добавление скриншота в соответствии с запросом.
![Screenshot for end result]()
Ответ 2
Вы можете использовать этот метод:
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)
val canvas = Canvas(bitmap)
draw(canvas)
BitmapDescriptorFactory.fromBitmap(bitmap)
}
}
Ответ 3
Может быть, немного опоздал к игре, но это прекрасно работает с Google Maps 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()
просто возвращает инициализированную getMarkerIcon()
переменную-член locationMarkerIcon
.
Скриншот:
![enter image description here]()
Ответ 4
преобразовать векторный ресурс в растровый объект и использовать 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;
}
Ответ 5
Если кто-то ищет в kotlin здесь метод для вас:
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)
и этот для установки маркера для вашей карты спасибо Лео Droidcoder из его ответа только я преобразовал его в kotlin
Ответ 6
Попробуйте это
MarkerOptions op = new MarkerOptions();
op.position(src_latlng);
Marker origin_marker = googleMap.addMarker(op);
Bitmap bitmap = getBitmap(this,R.drawable.ic_map_marker);
origin_marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
getBitmap
public Bitmap getBitmap(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof BitmapDrawable) {
return BitmapFactory.decodeResource(context.getResources(), drawableId);
} else if (drawable instanceof VectorDrawable) {
return getBitmap((VectorDrawable) drawable);
} else {
throw new IllegalArgumentException("unsupported drawable type");
}
}
ic_map_marker.xml
<vector android:height="32dp" android:viewportHeight="512.0"
android:viewportWidth="512.0" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#f32f00" android:pathData="M288,284.8V480l-64,32V284.8c10.3,2.1 21,3.3 32,3.3S277.7,286.9 288,284.8zM384,128c0,70.7 -57.3,128 -128,128c-70.7,0 -128,-57.3 -128,-128S185.3,0 256,0C326.7,0 384,57.3 384,128zM256,64c0,-17.7 -14.3,-32 -32,-32s-32,14.3 -32,32s14.3,32 32,32S256,81.7 256,64z"/>
</vector>