Since you know more about the google maps package, may I ask is it possible to show infoWindow for all markers by default?
I tried below that is looping through markers and showInfoWindow but that shows only the last marker's info window.
Thank you very much for your help.
// // Show the info windows for all markers
for (final marker in _markers) {
print(marker.infoWindow.title);
await Future.delayed(const Duration(milliseconds: 300));
_googleMapController.showMarkerInfoWindow(marker.markerId);
}
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:ugv_fe/api/backend_api.dart';
import 'package:ugv_fe/models/vehicle2.dart';
import 'package:ugv_fe/pages/vehicles_list.dart';
import 'package:ugv_fe/provider/theme_provider.dart';
class LandingPage extends StatefulWidget {
const LandingPage({Key? key}) : super(key: key);
@override
State<LandingPage> createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
Timer? _timer;
bool _isPageOpen = true;
int selectedVehicleIndex = 0;
static LatLng current_Camera_posistion = const LatLng(0, 0);
String? _mapStyle;
late GoogleMapController _googleMapController;
static List<Vehicle> allVehiclesList = [];
bool showVehiclesList = false;
bool markersLoading = false;
bool vehiclesLoaded = false;
// final Map<String, Marker> _markers = {};
final List<Marker> _markers = [];
int markerFlag = -1;
// final Set<Marker>? _markers = <Marker>{};
BitmapDescriptor? activeMarker;
BitmapDescriptor? offlineMarker;
BitmapDescriptor? alertMarker;
BitmapDescriptor? activeMarkerSelected;
BitmapDescriptor? offlineMarkerSelected;
BitmapDescriptor? alertMarkerSelected;
Future<BitmapDescriptor> getIcon(
{required String imagePath, required int width}) async {
final Uint8List markerIcon = await getBytesFromAsset(imagePath, width);
BitmapDescriptor icon = BitmapDescriptor.fromBytes(markerIcon);
return icon;
}
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();
}
Future<void> setMarkerIcon() async {
print("Trying to setup Marker");
print(markersLoading);
activeMarker =
await getIcon(imagePath: 'assets/images/marker_online.png', width: 100);
activeMarkerSelected =
await getIcon(imagePath: 'assets/images/marker_online.png', width: 130);
offlineMarker = await getIcon(
imagePath: 'assets/images/marker_offline.png', width: 100);
offlineMarkerSelected = await getIcon(
imagePath: 'assets/images/marker_offline.png', width: 130);
alertMarker =
await getIcon(imagePath: 'assets/images/marker_alert.png', width: 100);
alertMarkerSelected =
await getIcon(imagePath: 'assets/images/marker_alert.png', width: 130);
setState(() {
markersLoading = true;
});
}
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(double.tryParse(allVehiclesList[0].vehicleLatitude!) ?? 0.0,
double.tryParse(allVehiclesList[0].vehicleLongitude!) ?? 0.0),
zoom: 18,
);
Future<void> _onMapCreated(GoogleMapController controller) async {
_googleMapController = controller;
setState(() {
_markers.clear();
print("VehiclesList inside onMapCreated");
print(allVehiclesList);
var cnt = 0;
for (final vehicle in allVehiclesList) {
int idMarker = cnt;
_markers.add(Marker(
consumeTapEvents: true,
icon: (vehicle.vehicleIsOnline! &&
vehicle.vehicleCurrentStatus == 'Active')
? activeMarker!
: (vehicle.vehicleCurrentStatus == 'Alert')
? alertMarker!
: offlineMarker!,
markerId: MarkerId(idMarker.toString()),
position: LatLng(double.tryParse(vehicle.vehicleLatitude!)!,
double.tryParse(vehicle.vehicleLongitude!)!),
infoWindow: InfoWindow(
title: vehicle.vehicleName,
),
onTap: () {
if (markerFlag != idMarker) {
setState(() {
// resetMarkers();
if (markerFlag != -1) {
Vehicle oldSelectedVehicle = allVehiclesList[markerFlag];
_markers[markerFlag] = _markers[markerFlag].copyWith(
iconParam: (oldSelectedVehicle.vehicleIsOnline! &&
oldSelectedVehicle.vehicleCurrentStatus == 'Active')
? activeMarker!
: (oldSelectedVehicle.vehicleCurrentStatus == 'Alert')
? alertMarker!
: offlineMarker!,
);
}
_markers[idMarker] = _markers[idMarker].copyWith(
iconParam: (vehicle.vehicleIsOnline! &&
vehicle.vehicleCurrentStatus == 'Active')
? activeMarkerSelected!
: (vehicle.vehicleCurrentStatus == 'Alert')
? alertMarkerSelected!
: offlineMarkerSelected!,
);
markerFlag = idMarker;
});
}
showVehiclesListPopup(idMarker);
},
));
// _googleMapController
// .showMarkerInfoWindow(MarkerId(idMarker.toString()));
// _markers[vehicle.vehicleName] = marker;
cnt += 1;
}
});
// // Show the info windows for all markers
for (final marker in _markers) {
print(marker.infoWindow.title);
await Future.delayed(const Duration(milliseconds: 300));
_googleMapController.showMarkerInfoWindow(marker.markerId);
}
}
getData() async {
var result = await CallApi().getVehicles();
allVehiclesList = result;
print("Inside Get Data");
print(allVehiclesList);
for (final vehicle in allVehiclesList) {
print(vehicle.vehicleName);
}
setState(() {
vehiclesLoaded = true;
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
getData();
setMarkerIcon();
rootBundle.loadString('assets/map_style.txt').then((string) {
_mapStyle = string;
});
_timer = Timer.periodic(const Duration(seconds: 30), (Timer t) {
if (_isPageOpen) {
reloadGetData();
} else {
_timer?.cancel();
}
});
}
@override
void dispose() {
_isPageOpen = false;
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
!markersLoading || !vehiclesLoaded
? const SpinKitWave(size: 32, color: AppThemes.appCommonRedColor)
: GoogleMap(
onTap: (value) {
setState(() {
markerFlag = -1;
});
},
mapType: MapType.hybrid,
onMapCreated: _onMapCreated,
initialCameraPosition: _kGooglePlex,
markers: _markers.toSet(),
mapToolbarEnabled: false,
zoomControlsEnabled: false,
padding: const EdgeInsets.all(150),
onCameraMove: (CameraPosition position) {
setState(() {
current_Camera_posistion = LatLng(
position.target.latitude, position.target.longitude);
});
},
),
Positioned(
top: 20,
left: 5,
child: Card(
elevation: 20,
child: SizedBox(
// color: const Color(0xFFFAFAFA),
width: 40,
height: 100,
child: Column(
children: <Widget>[
IconButton(
icon: const Icon(Icons.add),
onPressed: () async {
var currentZoomLevel =
await _googleMapController.getZoomLevel();
print(currentZoomLevel);
currentZoomLevel = currentZoomLevel + 2;
_googleMapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: current_Camera_posistion,
zoom: currentZoomLevel,
),
),
);
}),
const SizedBox(height: 2),
IconButton(
icon: const Icon(Icons.remove),
onPressed: () async {
var currentZoomLevel =
await _googleMapController.getZoomLevel();
print(currentZoomLevel);
currentZoomLevel = currentZoomLevel - 2;
if (currentZoomLevel < 0) currentZoomLevel = 0;
_googleMapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: current_Camera_posistion,
zoom: currentZoomLevel,
),
),
);
}),
],
),
),
),
),
// Positioned(
// top: 20,
// right: 5,
// child: FloatingActionButton(
// mini: true,
// backgroundColor: AppThemes.appCommonBGColor,
// child: const Icon(Icons.refresh_rounded),
// onPressed: () {
// print('Pressed reload');
// reloadGetData();
// })),
showVehiclesList
? Positioned(
right: 10,
bottom: MediaQuery.of(context).size.height * 0.5 + 62,
child: FloatingActionButton(
child: const Icon(
Icons.close,
color: AppThemes.appCommonRedColor,
),
backgroundColor:
Theme.of(context).colorScheme.surface.withOpacity(0.7),
mini: true,
onPressed: hideVehiclesListPopup),
)
: const SizedBox.shrink(),
showVehiclesList
? Positioned(
left: 10,
right: 10,
bottom: 58,
child: VehiclesList(
vehiclesList: allVehiclesList,
selectedVehicleIndex: selectedVehicleIndex,
))
: const SizedBox.shrink(),
],
);
}
showVehiclesListPopup(int index) {
setState(() {
showVehiclesList = true;
selectedVehicleIndex = index;
// print("I am here");
// print(vehicleId);
// selectedVehicleIndex = allVehiclesList
// .indexWhere((vehicle) => vehicle.vehicleId == vehicleId);
// print(selectedVehicleIndex);
});
}
hideVehiclesListPopup() {
setState(() {
showVehiclesList = false;
});
}
resetMarkers() {
var index = 0;
setState(() {
for (final vehicle in allVehiclesList) {
print(vehicle.vehicleId);
_markers[index] = _markers[index].copyWith(
iconParam: (vehicle.vehicleIsOnline! &&
vehicle.vehicleCurrentStatus == 'Active')
? activeMarker!
: (vehicle.vehicleCurrentStatus == 'Alert')
? alertMarker!
: offlineMarker!,
);
}
});
}
Future<void> reloadGetData() async {
await getData();
await setMarkerIcon();
await _onMapCreated(_googleMapController);
print('Data Reloaded Landing Page');
setState(() {
// Your code here
});
}
}