【问题标题】:Flutte: Animate Goolge Map marker like native android?Flutter:像原生安卓一样动画谷歌地图标记?
【发布时间】:2022-02-10 20:45:39
【问题描述】:

im trying to animate my google maps marker with continuous LatLng from json API but the probelm is im 使用未来从我的 API 获取数据,所以这是一次快照,标记仍然在同一位置我尝试了具有补间状态的动画功能,但这仍然无法正常工作标记 这是 GoogleMaps 小部件的代码

final List<Marker> _markers = <Marker>[];

动画? _动画; 后期 GoogleMapController _controller;

最终_mapMarkerSC = StreamController();

StreamSink 获取 _mapMarkerSink => _mapMarkerSC.sink; Stream 获取 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,

    ],
  ),
);

}

动画功能

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)),/ 锚点:常量偏移量(0.5,0.5), 旋转:testList[i].heading!.toDouble(), 可拖动:假, );

      _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,
      );
    });
  }
});

这是 fetchData() 的未来

List<SingleVehicleProvider> testList = [];

未来? _未来;

Future fetchData() 异步 { SharedPreferences 首选项 = 等待 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;

}

我在这个问题上停留了 2 周,我尝试使用 animarker 包并尝试使用 Stream 获取数据,但它给了我错误,请帮助我解决这个问题

i`m trying to create my screen like in this GIF URL 但我的屏幕是静态的

【问题讨论】:

    标签: flutter google-maps


    【解决方案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;
        }
    

    这很简单,我以前做的所有事情都会对您有所帮助,并且总是打电话给 setState(() { _addMarker( LatLng(event.latitude, event.longitude), "origin", BitmapDescriptor.defaultMarker, );

    } 这是我用来根据流更新标记的代码

    【讨论】:

    • 我一个字都看不懂
    • 问题是 im not trying to get device location on which my app will be executing im 试图从我的 API 获取位置和 LatLng
    • 不使用list只使用Map markers = {};
    • 您在标记列表中添加新标记而不是使用地图,以便在更新值时仅更新 id 标记
    • 好的,这部分我理解,但我如何从我的 API 获取流或连续 LatLng?
    猜你喜欢
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多