
Google Map là từ khóa chắc hẳn không còn xa lạ với các Developer mobile và web. Khi thêm Maps SDK vào dự án của mình, bạn có thể sử dụng các dữ liệu của Google Maps, hiển thị bản đồ và thực hiện các tác vụ trên bản đồ. Các bạn có thể thực hiện thêm Maps SDK vào dự án của mình qua Google Maps Document. Còn hôm nay. mình sẽ hướng dẫn các bạn cách để Tùy chỉnh Marker trong Google Map với Flutter. Let’s start
pubspect.yaml
.svg
nên mình thêm thư viện này để convert fileTạo một StatefulWidget với Widget GoogleMap như này:
@overrideWidget build(BuildContext context) {return Scaffold(body: SafeArea(child: Obx(() {return _mapController.isLoading.value? const Center(child: CircularProgressIndicator()): _buildGoogleMap();},),),);}Widget _buildGoogleMap() {return GoogleMap(markers: markers,initialCameraPosition: const CameraPosition(target: LatLng(35.226642, 136.735311),zoom: 15.0,),);}void _initMarker() {for (var place in _mapController.places) {markers.add(Marker(markerId: MarkerId(place.id),position: place.latLng,infoWindow: InfoWindow(title: place.name),icon: BitmapDescriptor.defaultMarker,),);}}
initialCameraPosition
: Cần truyền vào vị trí camera focus vào khi map được khởi tạo markers: Truyền vàoSet<>
Vậy là xong được 1/3 quãng đường rồi :D
Vì icon
chỉ nhận dạng truyền vào là Bitmap nên chúng ta cần convert ảnh hoặc Widget qua Bitmap trước thì mới sử dụng được nhé
static Future<BitmapDescriptor> _bitmapSvg(BuildContext context,int id,) async {// Default bitmap is icon pin_redString svgString = await DefaultAssetBundle.of(context).loadString('assets/images/ic_pin_red.svg');if (id % 2 == 1) {svgString = await DefaultAssetBundle.of(context).loadString('assets/images/ic_pin_blue.svg');}DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, 'svg');// Calculate parameters of bitmap (width - height)MediaQueryData queryData = MediaQuery.of(context);double devicePixelRatio = queryData.devicePixelRatio;double width = 24 * devicePixelRatio;double height = 24 * devicePixelRatio;// Draw to image and convert to byteui.Picture picture = svgDrawableRoot.toPicture(size: Size(width, height));ui.Image image = await picture.toImage(width.toInt(), height.toInt());ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);return BitmapDescriptor.fromBytes(bytes!.buffer.asUint8List());}
- image.toByteData(format: ui.ImageByteFormat.png) : Có thể thay
png
bằngrawUnmodified
,rawRgba
hoặcrawStraightRgba
để giảm độ phân giải của bitmap. Note: Khi gán kích thước cho ảnh, các bạn nên tính toán theo kích thước device để ảnh không bị không tương thích với các device khác nhau nhé
Sau đó thì vứt nó vào chỗ icon
trong initMarker để convert thôi
void _initMarker() async {for (var place in _mapController.places) {String id = place.id;final bitmap = await BitmapConvert.bitmapSvg(context, int.parse(id));markers.add(Marker(markerId: MarkerId(id),position: place.latLng,infoWindow: InfoWindow(title: place.name),icon: bitmap),);}}
Cùng xem thành quả nhé
Qua bài này thì các bạn có thể tự custom marker với bất cứ định dạng ảnh nào mà bạn muốn. Ở bài viết tiếp theo mình sẽ hướng dẫn các bạn cách để custom Marker với Widget nhé. See yah