Custom marker in google maps in android with vector asset icon

前端 未结 9 1143
小鲜肉
小鲜肉 2020-12-02 09:50

How can we achieve a map marker icon with vector asset file, the way google shows it like this, programatically:

Update:

m         


        
相关标签:
9条回答
  • 2020-12-02 10:03

    Might be a bit late to the game but this works great with 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);
    }
    

    Initialized as:

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

    Usage:

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

    Note: getMarkerIcon() just returns the initialized non null locationMarkerIcon member variable.

    Screenshot:

    0 讨论(0)
  • 2020-12-02 10:10

    If someone who is looking for in kotlin here is the method for you :

      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);
    }
    

    above method will convert you vector icon to bitmapdescritor

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

    and this one for setting marker for your map thanks for Leo Droidcoder from his answer only i have converted it to kotlin

    0 讨论(0)
  • 2020-12-02 10:12

    In Kotlin: I used the below code to show the SVG image on Marker. Here, I used no background color / 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)
    }
    

    Use like this way:

    googleMap?.addMarker(MarkerOptions().position(LatLng(it.latitude!!, it.longitude!!))
                .title(it.airLineDetails))?.setIcon(
                getBitmapDescriptorFromVector(requireContext(), R.drawable.ic_flight_blue))
    

    Screen Shot:

    0 讨论(0)
  • 2020-12-02 10:13

    convert vector resource to bitmap object and use BitmapDescriptorFactory.fromBitmap(bitmap)

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

    Bitmap converter:

     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 讨论(0)
  • 2020-12-02 10:14

    I was looking for exact same requirement, and seeing this question made me happy at first, but same as @Shuddh I wasn't happy with the given answers.

    To make my story short, I am using following code for this requirement:

    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);
    }
    

    and a usage example:

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

    Note: you may wish to use different bounding for your vectors, my vectors were 24dp in size and I've used a 48dp png image(blue-part, which can be a vector too) as background.

    UPDATE: Adding screenshot as it was requested.

    0 讨论(0)
  • 2020-12-02 10:24

    You can use this method:

    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);
    }
    

    So your code will look like:

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

    Edit:
    In Kotlin it may look like:

    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)
            }
        }
    
    0 讨论(0)
提交回复
热议问题