FontAwesome icons in Android's MapFragment

I spent some time trying to customize MapMarkers in Google Maps Android SDK, I hope this guide is useful if you're trying to integrate FontAwesome's icons in your app's map layout. Android Iconfiy is a great library that provides FontAwesome icons in Android, so we'll use that as our source of icons.

Google Map's custom markers needs a BitmapDescriptor:

// Specify an icon
Iconify.IconValue iv = Iconify.IconValue.fa_car;

// Get the bitmap descriptor, we need to build this yet
BitmapDescriptor customMarker = getCustomMarker(iv);

// Setup the marker
MarkerOptions marker = new MarkerOptions()  
                .position(new LatLng(latitude, longitude))
                .title("My title")
                .snippet("My snippet")
                .icon(customMarker)
                .draggable(false);

// Add it to your map instance
mMap.addMarker(marker);  

We can generate the BitmapDescriptor as follows:

public BitmapDescriptor getCustomMarker(final IconValue iconValue) {  
    IconDrawable id = new IconDrawable(getBaseContext(), iconValue).actionBarSize();
    Drawable d = id.getCurrent();
    Bitmap bm = Bitmap.createBitmap(id.getIntrinsicWidth(), id.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bm);

    d.draw(c);

    return BitmapDescriptorFactory.fromBitmap(bm);
}

This generate a stroked icon:

I would rather have the shape filled. This is somehow tricky since we need to override the IconDrawable's draw method:

public BitmapDescriptor getCustomMarker(IconValue iconValue) {  
    IconDrawable id = new IconDrawable(getBaseContext(), iconValue) {
         @Override
         public void draw(Canvas canvas) {
             // The TextPaint is defined in the constructor
            // but we override it here
            TextPaint paint = new TextPaint();
            paint.setTypeface(Iconify.getTypeface(getBaseContext()));
            paint.setStyle(Paint.Style.STROKE_AND_FILL);
            paint.setTextAlign(Paint.Align.CENTER);
            paint.setUnderlineText(false);

            // If you need a custom color specify it here
            paint.setColor(Color.BLACK);

            paint.setAntiAlias(true);
            paint.setTextSize(getBounds().height());
            Rect textBounds = new Rect();
            String textValue = String.valueOf(iconValue.character());
            paint.getTextBounds(textValue, 0, 1, textBounds);
            float textBottom = (getBounds().height() - textBounds.height()) / 2f + textBounds.height() - textBounds.bottom;
            canvas.drawText(textValue, getBounds().width() / 2f, textBottom, paint);
        }

    }.actionBarSize();
     Drawable d = id.getCurrent();
    Bitmap bm = Bitmap.createBitmap(id.getIntrinsicWidth(), id.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bm);

    d.draw(c);

    return BitmapDescriptorFactory.fromBitmap(bm);
}

This gives us a filled icon:

comments powered by Disqus