【问题标题】:How To Set Initial Camera Position To The Current Device's Latitude and Longitude Using Google Maps For Flutter如何使用 Google Maps For Flutter 将初始相机位置设置为当前设备的纬度和经度
【发布时间】:2019-08-26 11:33:59
【问题描述】:

我正在为我的应用程序使用谷歌地图颤振插件。我希望初始相机位置目标(LatLng)完全等于当前设备的纬度和经度,以便启动时的相机显示用户当前所在的位置。但是,我在尝试这样做时遇到了问题。我曾尝试使用 Location 和 Geolocator 包,但没有明确的示例说明如何做我想要实现的目标。

当我尝试将 currentLocation.latitudecurrentLocation.longitude 用于 Location 包作为相机目标中 Latlng 的值时,我遇到了以下错误。

"只有静态成员可以被初始化器访问"

坦率地说,我不知道在这种情况下这意味着什么。我已经阅读了一些示例,但没有一个清楚地实现了我真正想要实现的目标

import 'package:flutter/cupertino.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';


class Map extends StatefulWidget {
  @override
  State<Map> createState() => MapState();
}

class MapState extends State<Map> {
  Completer<GoogleMapController> _controller = Completer();
  var currentLocation = LocationData;

  var location = new Location();

 Future _getLocation() async {
    try {
      location.onLocationChanged().listen((LocationData currentLocation) {
        print('Latitude:${currentLocation.latitude}');
        print('Longitude:${currentLocation.longitude}');
        return LatLng(currentLocation.latitude, currentLocation.longitude);
      });
    } catch (e) {
     print('ERROR:$e');
      currentLocation = null;
    }

  }
  static final CameraPosition _currentPosition = CameraPosition(
    target: LatLng(currentLocation.latitude  ,  currentLocation.longitude),
    zoom: 14.4746,
  );

  @override
  void initState() {
    _getLocation();
    super.initState();
  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _currentPosition,
        zoomGesturesEnabled: true,
        myLocationButtonEnabled: true,
        rotateGesturesEnabled: true,
        tiltGesturesEnabled: true,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),

    );
  }


}

这是我的代码 sn-p 在 _currentPosition final 上产生错误,代表相机位置,使用定位器包将其等同于当前设备的纬度和经度,但 Flutter 抱怨。我不知道如何正确地做到这一点。我希望 latlng 目标是设备的 latlng

【问题讨论】:

    标签: google-maps flutter


    【解决方案1】:

    在获取用户当前位置时显示地图小部件时出现错误的问题是,获取用户的实际当前位置是一个异步操作,因此在整个过程中初始位置将为空,因此我们设置了一个条件:在我们等待异步操作完成时运行,然后显示地图,此时值将非空。我已经重构了代码并改用了 geolocator 包

    import 'package:flutter/cupertino.dart';
    import 'dart:async';
    import 'package:flutter/material.dart';
    import 'package:geolocator/geolocator.dart';
    import 'package:google_maps_flutter/google_maps_flutter.dart';
    
    class Map extends StatefulWidget {
      @override
      _MapState createState() => _MapState();
    }
    
    class _MapState extends State<Map> {
      Completer<GoogleMapController> controller1;
    
      //static LatLng _center = LatLng(-15.4630239974464, 28.363397732282127);
      static LatLng _initialPosition;
      final Set<Marker> _markers = {};
      static  LatLng _lastMapPosition = _initialPosition;
    
      @override
      void initState() {
        super.initState();
        _getUserLocation();
      }
      void _getUserLocation() async {
        Position position = await Geolocator().getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
        List<Placemark> placemark = await Geolocator().placemarkFromCoordinates(position.latitude, position.longitude);
        setState(() {
          _initialPosition = LatLng(position.latitude, position.longitude);
          print('${placemark[0].name}');
        });
      }
    
    
      _onMapCreated(GoogleMapController controller) {
        setState(() {
          controller1.complete(controller);
        });
      }
    
      MapType _currentMapType = MapType.normal;
    
      void _onMapTypeButtonPressed() {
        setState(() {
          _currentMapType = _currentMapType == MapType.normal
              ? MapType.satellite
              : MapType.normal;
        });
      }
    
      _onCameraMove(CameraPosition position) {
        _lastMapPosition = position.target;
      }
    
      _onAddMarkerButtonPressed() {
        setState(() {
          _markers.add(
              Marker(
                  markerId: MarkerId(_lastMapPosition.toString()),
                  position: _lastMapPosition,
                  infoWindow: InfoWindow(
                      title: "Pizza Parlour",
                      snippet: "This is a snippet",
                      onTap: (){
                      }
                  ),
                  onTap: (){
                  },
    
                  icon: BitmapDescriptor.defaultMarker));
        });
      }
      Widget mapButton(Function function, Icon icon, Color color) {
        return RawMaterialButton(
          onPressed: function,
          child: icon,
          shape: new CircleBorder(),
          elevation: 2.0,
          fillColor: color,
          padding: const EdgeInsets.all(7.0),
        );
      }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: _initialPosition == null ? Container(child: Center(child:Text('loading map..', style: TextStyle(fontFamily: 'Avenir-Medium', color: Colors.grey[400]),),),) : Container(
            child: Stack(children: <Widget>[
              GoogleMap(
                markers: _markers,
    
                mapType: _currentMapType,
                initialCameraPosition: CameraPosition(
                  target: _initialPosition,
                  zoom: 14.4746,
                ),
                onMapCreated: _onMapCreated,
                zoomGesturesEnabled: true,
                onCameraMove: _onCameraMove,
                myLocationEnabled: true,
                compassEnabled: true,
                myLocationButtonEnabled: false,
    
              ),
              Align(
                alignment: Alignment.topRight,
                child: Container(
                    margin: EdgeInsets.fromLTRB(0.0, 50.0, 0.0, 0.0),
                    child: Column(
                      children: <Widget>[
                        mapButton(_onAddMarkerButtonPressed,
                            Icon(
                                Icons.add_location
                            ), Colors.blue),
                        mapButton(
                            _onMapTypeButtonPressed,
                            Icon(
                              IconData(0xf473,
                                  fontFamily: CupertinoIcons.iconFont,
                                  fontPackage: CupertinoIcons.iconFontPackage),
                            ),
                            Colors.green),
                      ],
                    )),
              )
            ]),
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      GeoLocator API 已更改,最新升级的 Geolocator 不再使用。相反,GeolocatorPlatform 是根据最新更新访问当前位置的新关键字

      LatLng currentPostion;
      
      void _getUserLocation() async {
              var position = await GeolocatorPlatform.instance
                  .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
          
              setState(() {
                currentPostion = LatLng(position.latitude, position.longitude);
              });
            }
      

      在您的 googlemap 中使用 currentPostion。 (定义 Latlag currentPosition);

      GoogleMap(
                   // onMapCreated: _onMapCreated,
                   initialCameraPosition: CameraPosition(
                     target: currentPostion,
                     zoom: 10,
                   ),  
                 ),
         
      

      【讨论】:

        【解决方案3】:

        您提到的错误意味着您正在尝试访问初始化程序中的非静态变量,在您的情况下为currentLocation

        由于currentLocation 的值对于MapState 类的每个实例都是不同的,因此您会收到上述错误。

        删除staticfinal 关键字并尝试在initState 函数中设置_currentPosition 变量,如下所示-

        class MapState extends State<Map> {
          Completer<GoogleMapController> _controller = Completer();
          var currentLocation = LocationData;
        
          var location = new Location();
          CameraPosition _currentPosition;
        
          Future _getLocation() async {
            try {
              location.onLocationChanged().listen((LocationData currentLocation) {
                print('Latitude:${currentLocation.latitude}');
                print('Longitude:${currentLocation.longitude}');
                return LatLng(currentLocation.latitude, currentLocation.longitude);
              });
            } catch (e) {
             print('ERROR:$e');
              currentLocation = null;
            }
        
          }
        
          @override
          void initState() {
            _getLocation();
            currentPosition = CameraPosition(
              target: LatLng(currentLocation.latitude  ,  currentLocation.longitude),
              zoom: 14.4746,
            );
            super.initState();
          }
        
          //Rest of the code remains same
        }
        

        【讨论】:

        • 我现在收到错误“未为“类型”类定义的吸气剂纬度和经度”
        • 我已经处理了这个错误,就像'CameraPosition _currentPosition;'但是,您的解决方案会导致错误“在 null 上调用了 getter 纬度”,它是一个 'noSuchMethodError:'
        • 我不确定,但可能是因为您只是将LocationData 的引用传递给currentLocation,而不是实例化对象。尝试改用var currentLocation = LocationData();
        猜你喜欢
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多