Android Flatter iOS-在加载Google Maps小部件之前,无法获取initialCameraPosition的当前位置

Android Flatter iOS-在加载Google Maps小部件之前,无法获取initialCameraPosition的当前位置,android,ios,google-maps,flutter,location,Android,Ios,Google Maps,Flutter,Location,我正在尝试在我的Flatter iOS应用程序中实现一个简单的映射功能。我遵循指南,从开始到结束,讨论了许多关于类似问题的问题 问题是在加载地图之前我无法获取当前位置,因此在initialCameraPosition中获取其LatLng将导致NPE。我可以做的是加载带有硬编码的initialCameraPosition的地图,然后正确加载当前位置,我可以通过拖动或单击右下角的浮动位置按钮将相机移动到地图上 以下是我的代码示例: import'包装:flift/cupertino.dart'; 进

我正在尝试在我的Flatter iOS应用程序中实现一个简单的映射功能。我遵循指南,从开始到结束,讨论了许多关于类似问题的问题

问题是在加载地图之前我无法获取当前位置,因此在
initialCameraPosition
中获取其LatLng将导致NPE。我可以做的是加载带有硬编码的
initialCameraPosition
的地图,然后正确加载当前位置,我可以通过拖动或单击右下角的浮动位置按钮将相机移动到地图上

以下是我的代码示例:

import'包装:flift/cupertino.dart';
进口“包装:颤振/材料.省道”;
导入“包:google_-maps_-flatter/google_-maps_-flatter.dart”;
导入“package:location/location.dart”;
const双摄像机_变焦=16;
const LatLng源位置=LatLng(37.3317,-122.0325086);
类MapPage扩展StatefulWidget{
@凌驾
_MapPageState createState()=>\u MapPageState();
}
类_MapPageState扩展状态{
谷歌地图控制器;
位置数据当前位置;
位置;
bool_服务已启用;
许可状态——已授予的许可;
@凌驾
void initState(){
super.initState();
位置=新位置();
location.onLocationChanged.listen((事件){
当前位置=事件;
});
setInitialLocation();
}
void setInitialLocation()异步{
_serviceEnabled=等待位置。serviceEnabled();
如果(!\u服务已启用){
_serviceEnabled=等待位置。requestService();
如果(!\u服务已启用){
返回;
}
}
_permissiongrated=等待位置。hasPermission();
如果(_permissiongrated==PermissionStatus.denied){
_permissiongrated=等待位置。requestPermission();
如果(_permissiongrated!=PermissionStatus.grated){
返回;
}
}
currentLocation=等待位置。getLocation();
}
void\u onMapCreated(谷歌地图控制器){
mapController=控制器;
}
CameraPosition initialCameraPosition(){
LatLng目标;
if(currentLocation!=null)
目标=纬度(currentLocation.latitude,currentLocation.longitude);
其他的
目标=源位置;
返回摄影机位置(目标:目标,缩放:摄影机\u缩放);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
背景颜色:Colors.orangeacent,
标题:文本(“地图”),
标题:对,
),
正文:
谷歌地图(
onMapCreated:_onMapCreated,
initialCameraPosition:initialCameraPosition(),
myLocationEnabled:对,
),
);
}
}
我知道获取当前位置是一个异步过程,因此我还尝试在正文部分使用
FutureBuilder

FutureBuilder(
未来:当前位置,
生成器:(上下文,快照){
if(snapshot.hasData){
LocationData currentLocation=snapshot.data;
返回谷歌地图(
onMapCreated:_onMapCreated,
initialCameraPosition:CameraPosition(
目标:拉丁美洲(
currentLocation.latitude,currentLocation.latitude)),
myLocationEnabled:对,
);
}else if(snapshot.hasrerror){
返回(文本(“${snapshot.error}”);
}
返回中心(
子对象:循环压缩机指示器(
背景颜色:Colors.orangeacent,
),
);
},
),
当我不得不从http GET请求中检索数据时,这就像一种魅力,但这一次它只会导致无休止的
CircularProgressIndicator

我从堆栈问题中尝试了许多其他解决方案,包括在
currentLocation
为null时返回空的
Container
,为
FutureBuilder snapshot.connectionState
创建条件,但同样没有成功

有趣的是,当我深入挖掘
Location.getCurrentLocation()
方法时,我发现:

///获取用户的当前位置。
///
///如果应用程序没有访问位置的权限,则引发错误。
///返回[LocationData]对象。
Future getLocation()异步{
返回LocationPlatform.instance.getLocation();
}
然后转到:

///获取用户的当前位置。
///
///如果应用程序没有访问位置的权限,则引发错误。
///返回[LocationData]对象。
未来getLocation(){
抛出未实现的错误();
}
这让我怀疑这个插件是否能正常工作

这是我的
颤振医生-v
结果:

[✓] Flutter (Channel master, v1.18.0-6.0.pre.82, on Mac OS X 10.15.4 19E287, locale pl-PL)
    • Flutter version 1.18.0-6.0.pre.82 at /Users/Vuco/flutter
    • Framework revision f35b673f2b (26 hours ago), 2020-04-19 02:45:01 +0530
    • Engine revision a5e0b2f2f2
    • Dart version 2.9.0 (build 2.9.0-1.0.dev 5b19445d9c)


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /Users/Vuco/Library/Android/sdk
    • Platform android-29, build-tools 29.0.3
    • Java binary at: /Users/Vuco/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/192.6308749/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.4.1, Build version 11E503a
    • CocoaPods version 1.9.1

[✓] Android Studio (version 3.6)
    • Android Studio at /Users/Vuco/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/192.6308749/Android Studio.app/Contents
    • Flutter plugin version 45.0.1
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)

[!] IntelliJ IDEA Ultimate Edition (version 2020.1)
    • IntelliJ at /Users/Vuco/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • For information about installing plugins, see
      https://flutter.dev/intellij-setup/#installing-the-plugins

[✓] VS Code (version 1.44.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.9.1

[✓] Connected device (1 available)
    • iPhone 8 • F60856B8-2C6E-401D-A0F9-06FFC7E09876 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-4 (simulator)

! Doctor found issues in 1 category.
以及我使用的依赖项:

google_maps_flutter: ^0.5.25+3
location: ^3.0.2

我建议改用这个软件包。这是我在所有应用程序中使用的,我需要在中获取位置并订阅位置,并且有很好的文档记录。尝试使用它,如果你对FutureBuilder的软件包仍然有问题,请用你的新代码更新帖子,我可以尝试进一步帮助你


如果您在创建地图之前没有初始化和检索位置,FutureBuilder就是一种解决方法。

在获得初始位置之前渲染地图的问题,我相信您已经意识到这一点。
FutureBuilder
可能会起作用,但可能会过度。你真正需要的只是一个布尔值

GoogleMapController mapController;
  LocationData currentLocation;
  Location location;
  bool _serviceEnabled;
  PermissionStatus _permissionGranted;
  CameraPosition _center =
      CameraPosition(target: SOURCE_LOCATION, zoom: CAMERA_ZOOM);
  bool isLoading = false;

  @override
  void initState() {
    super.initState();
    location = new Location();

    _getLocation();
  }

  _getLocation() async {
    setState(() {
      isLoading = true;
    });
    initialize();
    currentLocation = await location.getLocation();
    if (currentLocation == null) {
      return;
    }
    _center = CameraPosition(
        target: LatLng(currentLocation.latitude, currentLocation.longitude),
        zoom: CAMERA_ZOOM);

    setState(() {
      isLoading = false;
    });

    print("CurrentLocation: $currentLocation");
  }

  Future<void> initialize() async {
    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.DENIED) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.GRANTED) {
        return;
      }
    }
  }

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.orangeAccent,
        title: Text('Map'),
        centerTitle: true,
      ),
      body: isLoading
          ? CircularProgressIndicator()
          : Container(
              child: GoogleMap(
                onMapCreated: _onMapCreated,
                initialCameraPosition: _center,
                myLocationEnabled: true,
              ),
            ),
    );
  }
GoogleMapController-mapController;
位置数据当前位置;
位置;
bool_服务已启用;
许可状态——已授予的许可;
摄像机位置_中心=
摄影机位置(目标:源位置,缩放:摄影机缩放);
bool isLoading=false;
@凌驾
void initState(){
super.initState();
位置=新位置();
_格洛卡蒂