In flutter using google maps trying to place markers using a .png image with a custom color and size. I've got everything to work but the custom color, just can't figure out how to manipulate that without having multiple image assets all with different colors.
I'm using .png files stored as assets and using some codec and frameinfo to convert to bytes and manipulate the size. I have not been able to manipulate the color as well. I've seen examples of setting the base markers color but that doesn't let me specify the icon. I've seen examples of using canvas to build your own icon with shapes but that doesn't let me use a png as my icon (with the benefits of more formatting).
I'm trying to get both a custom icon and a custom color with a custom size.
Code looks kinda like this:
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'dart:ui';
class ExplorePage extends StatefulWidget {
@override
ExplorePageState createState() => ExplorePageState();
}
class ExplorePageState extends State<ExplorePage> {
final Map<String, Marker> markers = {};
StreamSubscription placeSubscription;
final LatLng center = const LatLng(37.6872, -97.3301);
void updateLists(List<PlaceList> PlaceList) async {
setState(() {
listPlaceList = PlaceList;
});
}
//called when the map is done being created
void onMapCreated(GoogleMapController controller) {
placeSubscription = placesBloc
.getPlaces()
//when the data changes update the map
.listen(updateMarkers);
}
//gets called when the data or filter changes, updates the markers list that is tied
//to the map and sets state so the map loads the markers
void updateMarkers(List<Place> placeList) async {
final Uint8List plannedIcon =
await getBytesFromAsset('assets/planned_marker.png', 100);
final Uint8List doneIcon =
await getBytesFromAsset('assets/done_marker.png', 100);
final Uint8List blankIcon =
await getBytesFromAsset('assets/blank_marker.png', 100);
setState(() {
placeList.forEach((Place place) {
if (place.latlon != null) {
final marker = Marker(
markerId: MarkerId(place.docId),
icon: place.done == null
? BitmapDescriptor.fromBytes(blankIcon)
: place.done == 'Done!'
? BitmapDescriptor.fromBytes(doneIcon)
: place.done == 'Planned'
? BitmapDescriptor.fromBytes(plannedIcon)
: BitmapDescriptor.fromBytes(blankIcon),
position: LatLng(place.latlon.latitude, place.latlon.longitude),
infoWindow: InfoWindow(
title: place.name,
snippet: place.name,
),
);
markers[place.name] = marker;
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
GoogleMap(
zoomGesturesEnabled: true,
myLocationButtonEnabled: false,
onMapCreated: onMapCreated,
markers: markers.values.toSet(),
initialCameraPosition: CameraPosition(
target: center,
zoom: 5.0,
),
),
],
));
}
Future<Uint8List> getBytesFromAsset(String path, int width) async {
ByteData data = await rootBundle.load(path);
Codec codec = await instantiateImageCodec(data.buffer.asUint8List(),
targetWidth: width);
FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ImageByteFormat.png))
.buffer
.asUint8List();
}
}