23

I'm trying to set a custom icon for the markers of my map, in my Flutter app. Since BitmapDescriptor.fromAsset() is deprecated, I'm sruggling to find how to use BitmapDescriptor.fromAssetImage().

I did not find any doc or Stackoverflow question about this.

This is the current way I'm creating it (without the custom image):

Marker(
          markerId: MarkerId(pos.toString()),
          position: pos,
          infoWindow: InfoWindow(
            title: store['store_name'],
            snippet: '',
          ),
          icon: BitmapDescriptor.defaultMarker));
Mickaël D
  • 447
  • 1
  • 4
  • 14

3 Answers3

50

Define a field in Class:

BitmapDescriptor myIcon;

Retrieve icon before the Map is ready.

@override
void initState() {
    BitmapDescriptor.fromAssetImage(
        ImageConfiguration(size: Size(48, 48)), 'assets/my_icon.png')
        .then((onValue) {
      myIcon = onValue;
    });
 }

set the Icon:

icon: myIcon;

Make sure you have set the icon in Flutter section of pubspec.yaml

 assets:
    - assets/my_icon.png
Akshar Patel
  • 8,998
  • 6
  • 35
  • 50
  • 1
    It works! Thanks for the clear answer. Marked as solution. – Mickaël D May 26 '19 at 12:04
  • @MickaëlD Always happy to help :) – Akshar Patel May 26 '19 at 12:07
  • 2
    Hello guys, I've loaded icon in initState before app loads, I confirmed it with loggers but after page loads I see an error `com.google.maps.api.android.lib6.common.apiexception.a: Failed to decode image. The provided image must be a Bitmap.' Can anyone help ? Many thanks – ricristian Aug 18 '19 at 03:52
  • 1
    I follow the step above it no any error but marker not display I don't know why – Meas Aug 31 '19 at 17:39
  • 4
    i'll try to use but return error .. software say Unhandled Exception: PlatformException(error, Failed to decode image. The provided image must be a Bitmap. how to solve? thanks – Daniele Angelini Dec 26 '19 at 09:12
  • @durduliu2009 I found using a `png` image works. I had the same error, but mine was because I had a slash in front of `assets`, like `/assets/icon.png`. Changing it to `assets/icon.png` solved the issue for me. – JVE999 Feb 28 '20 at 21:03
  • 6
    For some reason, I found that changing `Size(48, 48)` to `Size(10, 10)` does not change the size of the icon. – JVE999 Feb 28 '20 at 21:13
  • 6
    @JVE999 Size param of `ImageConfiguration` is Ignored by `BitmapDescriptor` – Théo Champion Mar 10 '20 at 13:28
  • 2
    Hi all, Do you encounter problems with sizing the icon? In my case it does not want to size to the desired value. Any ideas why? – Łukasz Garczynski Mar 14 '21 at 15:42
  • @AksharPatel question if I have multiple icons how should I do that? – Luis Fernando Scripcaru Jul 14 '21 at 19:02
23

A better solution will be to wrap the GoogleMap widget inside a FutureBuilder. Generate your markers in a separate Future, and assign the result of the future to the markers in the GoogleMap widget

FutureBuilder:

FutureBuilder(
  future: generateMarkers(positions),
  initialData: Set.of(<Marker>[]),
  builder: (context, snapshot) => GoogleMap(        
    initialCameraPosition: CameraPosition(target: LatLng(0, 0)),
    markers: snapshot.data,
  ),
);

markers generator:

Future<Set<Marker>> generateMarkers(List<LatLng> positions) async {
List<Marker> markers = <Marker>[];
for (final location in positions) {    
  final icon = await BitmapDescriptor.fromAssetImage(
      ImageConfiguration(size: Size(24, 24)), 'assets/my_icon.png');

  final marker = Marker(
    markerId: MarkerId(location.toString()),
    position: LatLng(location.latitude, location.longitude),
    icon: icon,
  );

  markers.add(marker);
}

return markers.toSet();

}
Jawad Hassan
  • 501
  • 3
  • 5
5

You could use it like:

Marker marker = Marker(
        icon: await BitmapDescriptor.fromAssetImage(
            ImageConfiguration(size: Size(48, 48)), 'assets/images/pin.png'
        )
    );