2017-02-21 230 views
15

我们怎样才能实现与矢量资源文件的地图标记图标,谷歌的方式显示它是这样,编程:自定义标记

map

更新:

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

在处理矢量资产时,这不起作用。提出问题的主要原因。与上面的代码错误:

java.lang.IllegalArgumentException:无法解码图像。提供的图像必须是位图。

+0

你也可以添加这个标记与PNG图像也如果你想。 –

+0

@RishabhMahatha我可以很容易地使用PNG,但问题是PNG是一个沉重的文件。要么我必须将其存储在我的apk中,或者必须从服务器调用它。但我特别需要从矢量资产文件。 – Shuddh

+0

@LucaNicoletti我必须使用矢量资产(或SVG)文件来实现这一点。我没有任何解决方法或方法来做到这一点。 – Shuddh

回答

2

我一直在寻找完全相同的要求,看到这个问题使我很高兴在第一,但相同@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

+0

我认为这会做到这一点。我会检查并标记答案。但是如果你有一个截图。请分享。 – Shuddh

+0

我添加了一个截图,我希望澄清最初的要求是什么! ;-)“我的意思是在一个Map引脚内重用向量” –

0

试试这个

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> 
+0

你可以解释vectorDrawable返回语句。什么是您正在使用的getBitmap方法。 – Shuddh

+0

另外我不认为这也会给我我想要的标记。因为图像中显示的标记是包含矢量素材的默认标记。但此代码将根据矢量资产生成图标,但不会在标记(蓝色部分)中生成图标。 – Shuddh

+0

@Shuddh您正在寻找的图标必须是自定义的。矢量资产应该定义蓝色和白色的汽车部分。然后你会将该矢量添加为图标。 –

12

你可以使用此方法:

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); 
+0

你试过了吗?现在我还没有看到这段代码! – Shuddh

+0

当然,我用它在我的项目 –

+0

这仍然解决我的问题!你的方法给我的只是那个汽车图标,而不是蓝色的背景。我需要保持这个背景加上那个drar这个图标。 – Shuddh