Flutter - 启用位置和动画相机到当前位置

Flutter - Enabling Location and Animate Camera to current location

我的目标写在标题上面

当我尝试将我的应用程序与 location-enabled 一起使用时,给定的功能运行得非常好。 但是当我尝试使用 location-disable 时,它要求我打开位置,所以我打开了它但功能不起作用。

我正在从 initState() 调用我的函数。

  firstLocation() async {
    await location.getLocation().then((LocationData locationData){
        //Sets the changing location in the Map Controller
        LatLng latLng = new LatLng(locationData.latitude, locationData.longitude);
        CameraUpdate cameraUpdate = CameraUpdate.newLatLngZoom(latLng, 15);
        mapController.animateCamera(cameraUpdate);
    });
  }
@override
  void initState() {
    super.initState();
    firstLocation();
  }

如果您想查看整个 class 代码:

class UserMapState extends State<UserMap> {

  GoogleMapController mapController;
  // Location location = new Location();

  Map<PolylineId, Polyline> _mapPolylines = {};
  int _polylineIdCounter = 1;

  final List<LatLng> points = <LatLng>[];

  Set<Marker> _markers = {};

  LatLng _lastMapPosition; // CLASS MEMBER, MAP OF MARKS
  bool driver_status = false;
  bool pick_request = false;

  GeoFirePoint _driverCurrentLocation;        

  Geoflutterfire geo = Geoflutterfire();

  var firestore = Firestore.instance;

  BitmapDescriptor myIcon;
  BorderRadiusGeometry radius;

  var location = new Location();

//   getDeviceLocation() async {
//     LocationData currentLocation;
//     try {
//       currentLocation = await location.getLocation();

//       print("locationLatitude: ${currentLocation.latitude}");
//       print("locationLongitude: ${currentLocation.longitude}"); 
//       setState(() {
//        this.latitude_current = currentLocation.latitude;
//        this.longitude_current = currentLocation.longitude;  
//       });
//  //rebuild the widget after getting the current location of the user
//     } on Exception {
//       currentLocation = null;
//     }
//   }

  getRoute() {
    firestore
      .collection(widget.institute)
      .document(widget.bus)
      .collection('Route')
      .orderBy('serial')
      .snapshots()
      .listen(
        (snap)  => snap.documents.forEach((doc){
          print(doc.data['LatLng'].latitude.toString());
          points.add(LatLng(doc.data['LatLng'].latitude, doc.data['LatLng'].longitude));                   
        }),
      );
  }

  firstLocation() async {
    location.getLocation().then((LocationData locationData){
        //Sets the changing location in the Map Controller
        LatLng latLng = new LatLng(locationData.latitude, locationData.longitude);
        CameraUpdate cameraUpdate = CameraUpdate.newLatLngZoom(latLng, 15);
        mapController.animateCamera(cameraUpdate);
    });
  }

  pickupRequest(bool value) async {
    var pos = await location.getLocation();
    GeoFirePoint point  = geo.point(latitude: pos.latitude, longitude: pos.longitude);
    firestore.collection(widget.institute).document(widget.bus).collection('Users').document(widget.uid).setData({
      'position': point.data,
      'pickup': value,
    });
  }

  @override
  void initState() {
    super.initState();
    getRoute();
    firstLocation();
    BitmapDescriptor.fromAssetImage(
      ImageConfiguration(size: Size(48, 48)), 'assets/bus_icon.png')
        .then((onValue) {
          myIcon = onValue;
    });
    radius = BorderRadius.only(
      topLeft: Radius.circular(12.0),
      topRight: Radius.circular(12.0),
    );
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Nomad"),
      ),
      drawer: DrawerWidget(name: widget.name, userID: widget.userID, institute: widget.institute,),
      body: SlidingUpPanel(
        panel: StreamBuilder(
          stream: firestore.collection(widget.institute.toString()).document(widget.bus.toString()).collection("Driver").snapshots(),
          builder: (context, snap) {
            if(snap.hasData) {
              List<DocumentSnapshot> snapshot = snap.data.documents;
              if(snapshot[0]['session'] == 1)
              {
                _lastMapPosition = LatLng(snapshot[0]['location']['geopoint'].latitude, snapshot[0]['location']['geopoint'].longitude);
                print(snapshot[0]['location']['geopoint'].latitude.toString());
                this._driverCurrentLocation = geo.point(latitude: snapshot[0]['location']['geopoint'].latitude, longitude: snapshot[0]['location']['geopoint'].longitude);
                print(_driverCurrentLocation.data['geopoint'].latitude.toString() + " " + _driverCurrentLocation.data['geopoint'].longitude.toString());
                this.driver_status = true;
                _getDriverMarker(_driverCurrentLocation.data['geopoint'].latitude, _driverCurrentLocation.data['geopoint'].longitude);

                return Container(
                  child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Center(
                          child: Text(
                            "Driver Name : " + snapshot[0]['name'] + "\n" + "Contact Driver : " + snapshot[0]['contact'],
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.black, fontSize: 24.0, fontWeight: FontWeight.w300)
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              } else {
                this.driver_status = false;
                _getDriverMarker(0.0, 0.0);
                return Container(
                  child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Center(
                          child: Text(
                            "Driver Name : " + snapshot[0]['name'] + "\n" + "Contact Driver : " + snapshot[0]['contact'],
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.black, fontSize: 24.0, fontWeight: FontWeight.w300)
                          ),
                        ),
                      ],
                    ),
                  ),
                );
              }
            } else {
              return Container(
                  child: Center(child: CircularProgressIndicator(),),
              );
            }
          },
        ),
        collapsed: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: radius,
          ),
          child: Center(
            child: driver_status == true ?
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  "Driver Online",
                  style: TextStyle(color: Colors.black, fontSize: 24.0, fontWeight: FontWeight.w300),
                ),
                StreamBuilder(
                  stream: firestore.collection(widget.institute).document(widget.bus).collection('Users').document(widget.uid).snapshots(),
                  builder: (context, snap) {
                    if(snap.hasData) {
                      if(snap.data['pickup'] == false) {
                        return MaterialButton(
                          child: Text(
                            "Pickup", 
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white, fontSize: 24.0, fontWeight: FontWeight.w300)
                          ),
                          color: Colors.blueAccent,
                          onPressed: () {
                            _addPickupMarker();
                          },
                        );
                      } else {
                        return MaterialButton(
                          child: Text(
                            "I am Riding", 
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white, fontSize: 24.0, fontWeight: FontWeight.w300)
                          ),
                          color: Colors.blueAccent,
                          onPressed: () {
                            _removePickupMarker();
                          },
                        );
                      }
                    } else {
                      return CircularProgressIndicator(backgroundColor: Colors.blueAccent,);
                    }
                  },
                ),
              ],
            ) :
             Text(
              "Driver Offline",
              style: TextStyle(color: Colors.black, fontSize: 24.0, fontWeight: FontWeight.w300),
            ),
          ),
        ),
        body: Stack(
          children: <Widget>[
            GoogleMap(
              initialCameraPosition: CameraPosition(
                target: LatLng(26.9124, 75.7873),
                zoom: 12
              ),
              rotateGesturesEnabled: true,
              compassEnabled: true,
              onMapCreated: _onMapCreated,
              myLocationEnabled: true,
              myLocationButtonEnabled: true,
              mapType: MapType.normal,
              polylines: Set<Polyline>.of(_mapPolylines.values),
              markers: _markers,
            ),
          ],
        ),
        backdropEnabled: true,
        borderRadius: radius,
      )
    );
  }

  void _add() {
    final String polylineIdVal = 'polyline_id_$_polylineIdCounter';
    _polylineIdCounter++;
    final PolylineId polylineId = PolylineId(polylineIdVal);

    final Polyline polyline = Polyline(
      polylineId: polylineId,
      consumeTapEvents: true,
      color: Colors.grey,
      width: 10,
      points: points,
    );

    setState(() {
      _mapPolylines[polylineId] = polyline;
    });
  }

  _getDriverMarker(lat, long) async{
    if(driver_status == true) {
      SchedulerBinding.instance.addPostFrameCallback((_) => setState(() {
          this._markers.clear();
          this._markers.add(Marker(
            markerId: MarkerId(_lastMapPosition.toString()),
            icon: myIcon,
            position: LatLng(lat, long),
          )); 
      }));
    } else {
      SchedulerBinding.instance.addPostFrameCallback((_) => setState(() {
          this._markers.clear();  
      }));
    }
  }

  void _addPickupMarker() {
    SchedulerBinding.instance.addPostFrameCallback((_) => setState(() {
      // this._markers.add(Marker(
      //   markerId: MarkerId('1'),
      //   icon: BitmapDescriptor.defaultMarker,
      //   position: LatLng(latitude_current, longitude_current),
      // ));
        this.pick_request = true;
        pickupRequest(true); 
    }));
  }

  void _removePickupMarker() {
    SchedulerBinding.instance.addPostFrameCallback((_) => setState(() {
      // this._markers.remove(Marker(
      //     markerId: MarkerId('1'),
      //     icon: BitmapDescriptor.defaultMarker,
      //     position: LatLng(latitude_current, longitude_current),
      // ));
        this.pick_request = false;
        pickupRequest(false); 
    }));
  }

  _onMapCreated(GoogleMapController controller) {
    _add();
    setState(() {
      mapController = controller;
    });
  }

}

检查以下内容 example/tutorial:

https://flutterbyexample.com/make-the-static-map-interactive/

如果您使用位置插件,您可以在每次用户更改其位置时获取位置流

    LatLng userPosition;

    location.onLocationChanged().listen((LocationData position) {
      setState(() {
          userPosition = LatLng(position.latitude, position.longitude);
        });
    });

然后您可以在每次位置变化时为相机设置动画

final GoogleMapController controller = await _controller.future;
  controller.animateCamera(
   CameraUpdate.newCameraPosition(
    CameraPosition(target: userPosition, zoom: zoomValue),
  ),
);