Question

I'm trying to create a Custom Marker that displays text with a number equal to the example below:

Example:

enter image description here

But when you run the application the text is not displayed, only the red ellipse appears without a number.

My Code

InicializeMap()##

 private void InicializeMap() 
{
    if (_googleMap == null) 
    {
        _googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.mapMapeamento)).getMap();

        LatLng pos = new LatLng(23.4555453556, 11.145315551);

        MapUtils mapUtils = new MapUtils(getApplicationContext());
        Bitmap bitmap = mapUtils.GetBitmapMarker();

        Marker marker = _googleMap.addMarker(new MarkerOptions()
                .position(pos)
                .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));

        // check if map is created successfully or not
        if (_googleMap == null) 
            Toast.makeText(getApplicationContext(), Mensagens.erroCriarMapa, Toast.LENGTH_SHORT).show();
    }
}

My method to create the Bitmap

public Bitmap GetBitmapMarker()
{
    Paint color = new Paint();
    color.setTextSize(35);
    color.setColor(Color.BLACK);

    int px = _mContext.getResources().getDimensionPixelSize(R.dimen.map_dot_marker_size);

    Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(mDotMarkerBitmap);
    canvas.drawText("Hello!", 30, 40, color);

    Drawable shape = _mContext.getResources().getDrawable(R.drawable.shape_marker_red);

    shape.setBounds(0, 0, mDotMarkerBitmap.getWidth(), mDotMarkerBitmap.getHeight());
    shape.draw(canvas);

    return mDotMarkerBitmap;
}

res/drawable/shape_marker_red

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <gradient
        android:angle="90"
        android:endColor="#f58383"
        android:startColor="#ee6464" />
    <stroke
        android:width="1dp"
        android:color="#a13939" />
</shape>
Was it helpful?

Solution 2

I got the following implementation and it worked. The implementation was as follows:

MapActivity class

MapUtils mapUtils = new MapUtils(getApplicationContext());
        Bitmap bitmap = mapUtils.GetBitmapMarker(getApplicationContext(), R.drawable.marker_blue, "1");

        Marker marker = _googleMap.addMarker(new MarkerOptions()
                .position(pos)
                .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));

MapUtils Class

public Bitmap GetBitmapMarker(Context mContext, int resourceId,  String mText) 
{
    try 
    {
        Resources resources = mContext.getResources();
        float scale = resources.getDisplayMetrics().density;
        Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);

        android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();

        // set default bitmap config if none
        if(bitmapConfig == null)
          bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;

        bitmap = bitmap.copy(bitmapConfig, true);

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);
        paint.setTextSize((int) (14 * scale));
        paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);

        // draw text to the Canvas center
        Rect bounds = new Rect();
        paint.getTextBounds(mText, 0, mText.length(), bounds);
        int x = (bitmap.getWidth() - bounds.width())/2;
        int y = (bitmap.getHeight() + bounds.height())/2;

        canvas.drawText(mText, x * scale, y * scale, paint);

        return bitmap;

    } 
    catch (Exception e) 
    {           
        return null;
    }
  }

OTHER TIPS

This is what I came up with.

enter image description here

First, declare your marker options to add the marker on the map.

MarkerOptions options = new MarkerOptions()
                        .position(new LatLng(GlobalApp.getInstance().getLoginUserInfo().getLatitude(),
                                GlobalApp.getInstance().getLoginUserInfo().getLongitude()))
                        .draggable(false)
                        .flat(false)
                        .icon(BitmapDescriptorFactory.fromBitmap(createStoreMarker()));
                Marker tempMarker = globalGoogleMap.addMarker(options);

Add a function to inflate a layout of your specification and you can get their reference and add whatever you want.This is the place where the magic happens.

private Bitmap createStoreMarker() {
        View markerLayout = getLayoutInflater().inflate(R.layout.store_marker_layout, null);

        ImageView markerImage = (ImageView) markerLayout.findViewById(R.id.marker_image);
        TextView markerRating = (TextView) markerLayout.findViewById(R.id.marker_text);
        markerImage.setImageResource(R.drawable.ic_home_marker);
        markerRating.setText(GlobalApp.getInstance().getLoginUserInfo().getStoreName());

        markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight());

        final Bitmap bitmap = Bitmap.createBitmap(markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        markerLayout.draw(canvas);
        return bitmap;
    }

This is the layout

store_marker_layout.xml I am inflating

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_store_marker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <TextView
        android:id="@+id/marker_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="8dp"
        android:text="dgdfgdfg"
        android:textColor="@android:color/black"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/marker_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/ic_home_marker" />

</LinearLayout>

Here you go. In this method, we're creating the BitmapDescriptor with a lap number centered into one of 3 drawables.

/**
 * @param lapNbr String
 * @return {@link BitmapDescriptor}
 */
private BitmapDescriptor createLapBitMap(String lapNbr) {
    // Determine which of the 3 icons to start from. 1 being the thinnest, 3 being the widest.
    Bitmap tmp = null;
    switch (lapNbr.length()) {
        case 1:
            tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon1);
            break;
        case 2:
            tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon2);
            break;
        // If a dude is recording more than 999 laps, let's just shoot him. :)
        default:
            tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon3);
            break;
    }

    if (tmp != null) {
        Bitmap.Config config = tmp.getConfig();
        if (config == null) {
            config = Bitmap.Config.ARGB_8888;
        }
        // Resource bitmpas are immutable, so we need to convert it to a mutable one.
        Bitmap bm = tmp.copy(config, true);
        if (bm != null) {
            // Draw text to the canvas center.
            Rect bounds = new Rect();
            mLapIconPaint.getTextBounds(lapNbr, 0, lapNbr.length(), bounds);
            int x = (bm.getWidth() - bounds.width()) / 2;
            int y = ((bm.getHeight() + bounds.height()) / 2) - 10; // bump it up just a bit
            Canvas c = new Canvas(bm);
            c.drawText(lapNbr, x, y, mLapIconPaint);
            return BitmapDescriptorFactory.fromBitmap(bm);
        }
    }

    // Return a default bitmap with a lap circle inside of the icon.
    return BitmapDescriptorFactory.fromResource(R.drawable.lap_icon1);
}

Why are you using a Bitmap here? It looks like a drawable will get the job done, and then you could programmatically change the .setText() of each variable depending on the assignment of the marker.

For example:

<Button android:id="@+id/markerButton"
    android:background="@drawable/markerDrawable"/>

Then:

markerButton.setText("1");

The solution to this is now available in the Google Maps SDK for Android Utility Library

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top