我们如何使用矢量资源文件实现地图标记图标,google以这样的方式显示它,以编程方式显示:
更新:
map.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.your_vector_asset))
.title(title);
这在处理矢量资产时不起作用。提出问题的主要原因。上述代码出错:
java.lang.IllegalArgumentException:无法解码图像。提供的图像必须是位图。
答案 0 :(得分:56)
您可以使用此方法:
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);
答案 1 :(得分:12)
我一直在寻找完全相同的要求,看到这个问题一开始让我开心,但和@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图像(蓝色部分,也可以是矢量)作为背景。
更新:根据请求添加屏幕截图。
答案 2 :(得分:5)
这是科特林爱好者的代码;)
private fun bitMapFromVector(vectorResID:Int):BitmapDescriptor {
val vectorDrawable=ContextCompat.getDrawable(context!!,vectorResID)
vectorDrawable!!.setBounds(0,0,vectorDrawable!!.intrinsicWidth,vectorDrawable.intrinsicHeight)
val bitmap=Bitmap.createBitmap(vectorDrawable.intrinsicWidth,vectorDrawable.intrinsicHeight,Bitmap.Config.ARGB_8888)
val canvas=Canvas(bitmap)
vectorDrawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap)
}
答案 3 :(得分:1)
可能会有点迟到,但这适用于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()
只返回初始化的非null locationMarkerIcon
成员变量。
<强>截图:强>
答案 4 :(得分:0)
将矢量资源转换为位图对象并使用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 :(得分:0)
如果有人在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);
}
上述方法会将您的矢量图标转换为bitmapdescritor
map.addMarker(new MarkerOptions()
.position(latLng)
.icon(bitmapDescriptorFromVector(getActivity(), R.drawable.your_vector_asset))
.title(title)
这是一个为您的地图设置标记的工具,感谢Leo Droidcoder从他的回答中得到的回报,我将其转换为Kotlin
答案 6 :(得分:0)
在Kotlin中:我使用以下代码在Marker上显示SVG图像。在这里,我没有使用背景色/ SVG。
fun getBitmapDescriptorFromVector(context: Context, @DrawableRes vectorDrawableResourceId: Int): BitmapDescriptor? {
val vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId)
val bitmap = Bitmap.createBitmap(vectorDrawable!!.intrinsicWidth, vectorDrawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
vectorDrawable.setBounds(0, 0, canvas.width, canvas.height)
vectorDrawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap)
}
以这种方式使用:
googleMap?.addMarker(MarkerOptions().position(LatLng(it.latitude!!, it.longitude!!))
.title(it.airLineDetails))?.setIcon(
getBitmapDescriptorFromVector(requireContext(), R.drawable.ic_flight_blue))
屏幕截图:
答案 7 :(得分:-1)
试试这个
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>
答案 8 :(得分:-1)
对于Kotlin用户。请检查下面的代码。我发现Fragment类。
class MapPinFragment : Fragment() {
private lateinit var googleMap1: GoogleMap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_map_pin, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mapView.onCreate(savedInstanceState)
mapView.onResume()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mapView.getMapAsync { googleMap ->
googleMap1 = googleMap as GoogleMap
addCustomMarker()
}
}
private fun addCustomMarker() {
Log.d("addCustomMarker", "addCustomMarker()")
if (googleMap1 == null) {
return
}
// adding a marker on map with image from drawable
googleMap1.addMarker(
MarkerOptions()
.position(LatLng(23.0225 , 72.5714))
.icon(BitmapDescriptorFactory.fromBitmap(getMarkerBitmapFromView()))
)
}
override fun onDestroy() {
super.onDestroy()
if (mapView != null)
mapView.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
private fun getMarkerBitmapFromView(): Bitmap? {
val customMarkerView: View? = layoutInflater.inflate(R.layout.view_custom_marker, null)
// val markerImageView: ImageView =
// customMarkerView.findViewById<View>(R.id.profile_image) as ImageView
customMarkerView?.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED );
customMarkerView?.layout(0, 0, customMarkerView.measuredWidth, customMarkerView.measuredHeight);
customMarkerView?.buildDrawingCache();
val returnedBitmap = Bitmap.createBitmap(
customMarkerView!!.measuredWidth, customMarkerView.measuredHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(returnedBitmap)
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN)
val drawable = customMarkerView.background
drawable?.draw(canvas);
customMarkerView.draw(canvas);
return returnedBitmap;
}
}