Is there a way to display custom markers with the official Flutter Google Maps plugin on the map? Can't find any way to do it based on the documentation.
Using an asset final Uint8List markerIcon = await getBytesFromAsset('assets/images/flutter. png', 100); final Marker marker = Marker(icon: BitmapDescriptor. fromBytes(markerIcon)); This will produce the following for 50, 100 and 200 width respectively.
You can use Flutter widgets for custom markers with this class
import 'package:flutter/material.dart';
import 'dart:typed_data';
import 'package:flutter/rendering.dart';
import 'dart:ui' as ui;
/// This just adds overlay and builds [_MarkerHelper] on that overlay.
/// [_MarkerHelper] does all the heavy work of creating and getting bitmaps
class MarkerGenerator {
final Function(List<Uint8List>) callback;
final List<Widget> markerWidgets;
MarkerGenerator(this.markerWidgets, this.callback);
void generate(BuildContext context) {
WidgetsBinding.instance
.addPostFrameCallback((_) => afterFirstLayout(context));
}
void afterFirstLayout(BuildContext context) {
addOverlay(context);
}
void addOverlay(BuildContext context) {
OverlayState overlayState = Overlay.of(context);
OverlayEntry entry;
entry = OverlayEntry(
builder: (context) {
return _MarkerHelper(
markerWidgets: markerWidgets,
callback: (List<Uint8List> bitmapList) {
// Given callback function
callback.call(bitmapList);
// Remove marker widget stack from Overlay when finished
entry.remove();
},
);
},
maintainState: true);
overlayState.insert(entry);
}
}
/// Maps are embeding GoogleMap library for Andorid/iOS into flutter.
///
/// These native libraries accept BitmapDescriptor for marker, which means that for custom markers
/// you need to draw view to bitmap and then send that to BitmapDescriptor.
///
/// Because of that Flutter also cannot accept Widget for marker, but you need draw it to bitmap and
/// that's what this widget does:
///
/// 1) It draws marker widget to tree
/// 2) After painted access the repaint boundary with global key and converts it to uInt8List
/// 3) Returns set of Uint8List (bitmaps) through callback
class _MarkerHelper extends StatefulWidget {
final List<Widget> markerWidgets;
final Function(List<Uint8List>) callback;
const _MarkerHelper({Key key, this.markerWidgets, this.callback})
: super(key: key);
@override
_MarkerHelperState createState() => _MarkerHelperState();
}
class _MarkerHelperState extends State<_MarkerHelper> with AfterLayoutMixin {
List<GlobalKey> globalKeys = [];
@override
void afterFirstLayout(BuildContext context) {
_getBitmaps(context).then((list) {
widget.callback(list);
});
}
@override
Widget build(BuildContext context) {
return Transform.translate(
offset: Offset(MediaQuery.of(context).size.width, 0),
child: Material(
type: MaterialType.transparency,
child: Stack(
children: widget.markerWidgets.map((i) {
final markerKey = GlobalKey();
globalKeys.add(markerKey);
return RepaintBoundary(
key: markerKey,
child: i,
);
}).toList(),
),
),
);
}
Future<List<Uint8List>> _getBitmaps(BuildContext context) async {
var futures = globalKeys.map((key) => _getUint8List(key));
return Future.wait(futures);
}
Future<Uint8List> _getUint8List(GlobalKey markerKey) async {
RenderRepaintBoundary boundary =
markerKey.currentContext.findRenderObject();
var image = await boundary.toImage(pixelRatio: 2.0);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
return byteData.buffer.asUint8List();
}
}
/// AfterLayoutMixin
mixin AfterLayoutMixin<T extends StatefulWidget> on State<T> {
@override
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => afterFirstLayout(context));
}
void afterFirstLayout(BuildContext context);
}
usage example
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:map_marker_sample/gist/Gist.dart';
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
List<Marker> markers = [];
@override
Widget build(BuildContext context) {
return Container(
child: Stack(
children: <Widget>[
GoogleMap(
initialCameraPosition:
CameraPosition(target: LatLng(45.811328, 15.975862), zoom: 8),
markers: markers.toSet(),
),
],
),
);
}
@override
void initState() {
super.initState();
MarkerGenerator(markerWidgets(), (bitmaps) {
setState(() {
markers = mapBitmapsToMarkers(bitmaps);
});
}).generate(context);
}
List<Marker> mapBitmapsToMarkers(List<Uint8List> bitmaps) {
List<Marker> markersList = [];
bitmaps.asMap().forEach((i, bmp) {
final city = cities[i];
markersList.add(Marker(
markerId: MarkerId(city.name),
position: city.position,
icon: BitmapDescriptor.fromBytes(bmp)));
});
return markersList;
}
}
// Example of marker widget
Widget _getMarkerWidget(String name) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 1.5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.black, width: 1),
color: Colors.white,
shape: BoxShape.rectangle,
),
child: Text(
name,
style: TextStyle(fontSize: 14, color: Colors.black),
),
),
);
}
// Example of backing data
List<City> cities = [
City("Zagreb", LatLng(45.792565, 15.995832)),
City("Ljubljana", LatLng(46.037839, 14.513336)),
City("Novo Mesto", LatLng(45.806132, 15.160768)),
City("Varaždin", LatLng(46.302111, 16.338036)),
City("Maribor", LatLng(46.546417, 15.642292)),
City("Rijeka", LatLng(45.324289, 14.444480)),
City("Karlovac", LatLng(45.489728, 15.551561)),
City("Klagenfurt", LatLng(46.624124, 14.307974)),
City("Graz", LatLng(47.060426, 15.442028)),
City("Celje", LatLng(46.236738, 15.270346))
];
List<Widget> markerWidgets() {
return cities.map((c) => _getMarkerWidget(c.name)).toList();
}
class City {
final String name;
final LatLng position;
City(this.name, this.position);
}
source Link: https://infinum.com/the-capsized-eight/creating-custom-markers-on-google-maps-in-flutter-apps
github repository :https://github.com/itsJoKr/markers_generator_sample
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With