'Flutte: Animate Goolge Map marker like native android?
im trying to animate my google maps marker with continuous LatLng from json API but the probelm is im using future to fetch data from my API so this is one time snapshot and the marker is still at the same position i tried Animation function with tween State but this isn`t working still stuck on same poisiton for marker
here is the code for GoogleMaps widget
final List<Marker> _markers = <Marker>[];
Animation? _animation; late GoogleMapController _controller;
final _mapMarkerSC = StreamController<List>();
StreamSink<List> get _mapMarkerSink => _mapMarkerSC.sink; Stream<List> get mapMarkerStream => _mapMarkerSC.stream;
final googleMap = StreamBuilder<List<Marker>>(
stream: mapMarkerStream,
builder: (context, snapshot){
return GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: LatLng(lati, longi),
zoom: 10,
),
zoomControlsEnabled: false,
onMapCreated: (GoogleMapController controller){
_controller = controller;
},
markers: Set<Marker>.of(snapshot.data ?? []),
padding: EdgeInsets.all(8),
);
},
);
return Scaffold(
body: Stack(
children: [
googleMap,
],
),
);
}
the animation function
setUpMarker() async {
for(int i = 0; i < testList.length; i++){
_setMarkerIcon() async {
_carIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(0.5, 0.5)),
"asset/icons/green1.png"
);
}
var currentLocationCamera = LatLng(testList[i].latitude!.toDouble(), testList[i].longitude!.toDouble());
final pickUpMarker = Marker(
markerId: MarkerId(testList[i].regNo!.toString()),
position: LatLng(currentLocationCamera.latitude, currentLocationCamera.longitude),
icon: _carIcon,
/*BitmapDescriptor.fromBytes(await getBytesFromAsset('assets/icons/green1.png', 70)),*/
infoWindow: InfoWindow(
title: testList[i].regNo!.toString(),
)
);
await Future.delayed(const Duration(milliseconds: 500));
_markers.add(pickUpMarker);
_mapMarkerSink.add(_markers);
}
}
animateCar(
double fromLat,
double fromLong,
StreamSink<List<Marker>> mapMarkerSink,
TickerProvider Provider,
GoogleMapController controller,
) async {
for(int i = 0; i < testList.length; i++){
setState(() {
_markers.clear();
getMarkers() {
_setMarkerIcon() async {
_carIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(0.5, 0.5)),
"asset/icons/green1.png"
);
}
}
var carMarker = Marker(
markerId: MarkerId("driverMakrer"),
position: LatLng(testList[i].latitude!.toDouble(), testList[i].longitude!.toDouble()),
icon: _carIcon,
/BitmapDescriptor.fromBytes(await getBytesFromAsset('assets/icons/green1.png', 60)),/ anchor: const Offset(0.5,0.5), rotation: testList[i].heading!.toDouble(), draggable: false, );
_markers.add(carMarker);
mapMarkerSink.add(_markers);
final animationController = AnimationController(
duration: const Duration(seconds: 1),
vsync: Provider,
);
Tween<double> tween = Tween(begin: 0, end: 1);
_animation = tween.animate(animationController)
..addListener(() async {
getMarkers() {
_setMarkerIcon() async {
_carIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(0.5, 0.5)),
"asset/icons/green1.png"
);
}
}
final v = _animation!.value;
double lng = v * testList[i].longitude!.toDouble() + (1 - v) * testList[i].longitude!.toDouble();
double lat = v * testList[i].latitude!.toDouble() + (1 - v) * testList[i].latitude!.toDouble();
LatLng newPos = LatLng(lat, lng);
if(_markers.contains(carMarker)) _markers.remove(carMarker);
carMarker = Marker(
markerId: MarkerId("driverMarker"),
position: newPos,/*LatLng(testList[i].latitude!.toDouble(), testList[i].longitude!.toDouble()),*/
icon: _carIcon,
/*BitmapDescriptor.fromBytes(await getBytesFromAsset('assets/icons/green1.png', 50)),*/
anchor: const Offset(0.5,0.5),
flat: true,
rotation: testList[i].latitude!.toDouble(),
draggable: false,
);
_markers.add(carMarker);
mapMarkerSink.add(_markers);
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
target: newPos,/*LatLng(testList[i].latitude!.toDouble(), testList[i].longitude!.toDouble()),*/
zoom: 15.5
))
);
});
animationController.forward();
});
}
}
Future.delayed(const Duration(seconds: 1)).then((value) {
for(int i = 0; i < testList.length; i++){
double latI;
double longI;
setState(() {
latI = testList[i].latitude!.toDouble();
longI = testList[i].longitude!.toDouble();
animateCar(
latI,
longI,
_mapMarkerSink,
this,
_controller,
);
});
}
});
and here is the future for fetchData()
List<SingleVehicleProvider> testList = [];
Future<List>? _future;
Future<List> fetchData() async { SharedPreferences prefs = await SharedPreferences.getInstance();
var secretKey = await prefs.get('secretKey') ?? null;
var customID = customervehiclesID;
var url = "http://api75.trackcaronline.com/api/Vehicle/GetSingleVehicleInfo/$customervehiclesID";
var result = await http.get(Uri.parse(url),
headers: {
'Authorization' : 'bearer $secretKey'
}
);
var jsonData = json.decode(result.body);
jsonData.forEach((e) async {
SingleVehicleProvider provider = await SingleVehicleProvider.fromJson(e);
testList.add(provider);
});
return testList;
}
i`m stuck at this probelm for 2 weeks i tried using animarker package and also tried fetching data using Stream but it gave me errors please help me on this
i`m trying to create my screen like in this GIF URL but my screen is static
Solution 1:[1]
Map<MarkerId, Marker> markers = {};
@override
Widget build(BuildContext context) {
return Scaffold(
body:
GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
myLocationEnabled: true,
tiltGesturesEnabled: true,
compassEnabled: true,
scrollGesturesEnabled: true,
zoomGesturesEnabled: true,
markers: Set<Marker>.of(markers.values),
onMapCreated: (GoogleMapController controller) {
usermap = controller;
},
),
)
);
}
_addMarker(LatLng position, String id, BitmapDescriptor descriptor)
{
MarkerId markerId = MarkerId(id);
Marker marker =
Marker(markerId: markerId, icon: descriptor, position: position);
markers[markerId] = marker;
}
that is simple that i used to do all thing this will help you and always call allways call setState(() { _addMarker( LatLng(event.latitude, event.longitude), "origin", BitmapDescriptor.defaultMarker, );
} that is code i use to update marker according to stream
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ali Hassan |
