Engineering

25 September, 2019

Use Network Images as Marker Icons on Flutter Google Maps

If you need to use Google Maps on your Flutter app and want to use custom icons for your map markers, you’re limited in terms of options. You can either use an asset or a file as a marker icon and that’s it!

António Valente

Software Engineer

Use Network Images as Marker Icons on Flutter Google Maps - Coletiv Blog

Currently, if you need to use Google Maps on your Flutter app and want to use custom icons for your map markers, you’re limited in terms of options. You can either use an asset or a file as a marker icon and that’s it.

Recently, while working on a project here at Coletiv, I needed to fetch the images of the markers from a REST API and display them on a Google Maps map.

Since everything is a widget in Flutter, you might think it’s possible to use any widget as a marker icon, and then hook an Image widget with the marker and be done with it. But, unfortunately, that’s not possible yet. You can track that feature request in this Github issue.

If you’re willing to let Google Maps go, I recommend that you try the Flutter Map package which allows you to use any widget as a marker icon. The problem is that this package only works with Map Tile API’s which are lacking in terms of performance comparing to the native Google Maps library.

Now, let’s check how I’ve implemented this feature.

1 - First implementation using HTTP

import 'package:http/http.dart' as http; final http.Response response = await http.get(imageUrl); BitmapDescriptor.fromBytes(response.bodyBytes);

Simple enough isn’t it? We have 2 problems with this implementation though. First, you’re performing a network request for every marker every time which can delay the loading. Second, the image is not resized, so we can have markers with different sizes, which is weird.

Let’s solve these problems.

2 - Caching the marker images with Flutter Cache Manager

import 'package:flutter_cache_manager/flutter_cache_manager.dart'; final File markerImageFile = await DefaultCacheManager().getSingleFile(imageUrl); final Uint8List markerImageBytes = await markerImageFile.readAsBytes(); BitmapDescriptor.fromBytes(markerImageBytes);

The DefaultCacheManager from the Flutter Cache Manager package will handle all the caching logic for you. First, it checks the cache to see if the file was already downloaded or not and if it was, it will check if the file is old (older than 30 days by default). If the file is recent it will be returned right away but if it needs to be refreshed or doesn’t exist, it will be downloaded and stored in the cache and then returned. You can customize this behavior by implementing the BaseCacheManager or by doing the caching mechanism yourself.

With this, you’ll see that the markers load much faster.

3 - Resizing the marker images

import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; final int targetWidth = 60; final File markerImageFile = await DefaultCacheManager().getSingleFile(imageUrl); final Uint8List markerImageBytes = await markerImageFile.readAsBytes(); final Codec markerImageCodec = await instantiateImageCodec( imageBytes, targetWidth: targetWidth, ); final FrameInfo frameInfo = await imageCodec.getNextFrame(); final ByteData byteData = await frameInfo.image.toByteData( format: ImageByteFormat.png, ); final Uint8List resizedMarkerImageBytes = byteData.buffer.asUint8List(); BitmapDescriptor.fromBytes(resizedMarkerImageBytes);

With this, you’re resizing the marker image to the targetWidth and converting it to PNG format which is required by the marker icon BitmapDescriptor.fromBytes method.

And that's it! Now you will have a properly resized marker with a network image icon that won’t take forever to load, showing in your Google Map widget. 👏 👏 👏

There is an example project at the Coletiv Github account that uses all this code and also implements Clusters on Google Maps, which is yet another unsupported feature that will be discussed in another article.

Be sure to check it out in the flutter google maps clusters repo, to see all the code with proper syntax highlighting and take a sneak peek at how I've implemented Clusters.

Note: You need to get your Google Maps API Key and add it here and here.

Flutter

Google Maps

Flutter Widget

Software Development

Join our newsletter

Be part of our community and stay up to date with the latest blog posts.

Subscribe

Join our newsletter

Be part of our community and stay up to date with the latest blog posts.

Subscribe

You might also like...

Go back to blogNext
How to support a list of uploads as input with Absinthe GraphQL

Engineering

26 July, 2022

How to support a list of uploads as input with Absinthe GraphQL

As you might guess, in our day-to-day, we write GraphQL queries and mutations for Phoenix applications using Absinthe to be able to create, read, update and delete records.

Nuno Marinho

Software Engineer

Flutter Navigator 2.0 Made Easy with Auto Router - Coletiv Blog

Engineering

04 January, 2022

Flutter Navigator 2.0 Made Easy with Auto Router

If you are a Flutter developer you might have heard about or even tried the “new” way of navigating with Navigator 2.0, which might be one of the most controversial APIs I have seen.

António Valente

Software Engineer

Enabling PostgreSQL cron jobs on AWS RDS - Coletiv Blog

Engineering

04 November, 2021

Enabling PostgreSQL cron jobs on AWS RDS

A database cron job is a process for scheduling a procedure or command on your database to automate repetitive tasks. By default, cron jobs are disabled on PostgreSQL instances. Here is how you can enable them on Amazon Web Services (AWS) RDS console.

Nuno Marinho

Software Engineer

Go back to blogNext