【发布时间】:2020-08-02 09:15:34
【问题描述】:
我正在尝试在我的 Flutter iOS 应用程序中实现一个简单的地图功能。我遵循了从Flutter location package readme 到Medium "Implement Real-time Location Updates on Google Maps in your Flutter Apps" article 的指南,最后解决了许多关于类似问题的堆栈问题。
问题是我在加载地图之前无法获取当前位置,因此在 initialCameraPosition 中获取其 LatLng 会导致 NPE。我可以做的是加载带有硬编码initialCameraPosition的地图,然后正确加载当前位置,我可以通过拖动或单击右下角的浮动位置按钮将相机移动到它。
这是我的代码示例:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
const double CAMERA_ZOOM = 16;
const LatLng SOURCE_LOCATION = LatLng(37.3317, -122.0325086);
class MapPage extends StatefulWidget {
@override
_MapPageState createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
GoogleMapController mapController;
LocationData currentLocation;
Location location;
bool _serviceEnabled;
PermissionStatus _permissionGranted;
@override
void initState() {
super.initState();
location = new Location();
location.onLocationChanged.listen((event) {
currentLocation = event;
});
setInitialLocation();
}
void setInitialLocation() 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;
}
}
currentLocation = await location.getLocation();
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
CameraPosition initialCameraPosition() {
LatLng target;
if (currentLocation != null)
target = LatLng(currentLocation.latitude, currentLocation.longitude);
else
target = SOURCE_LOCATION;
return CameraPosition(target: target, zoom: CAMERA_ZOOM);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.orangeAccent,
title: Text('Map'),
centerTitle: true,
),
body:
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: initialCameraPosition(),
myLocationEnabled: true,
),
);
}
}
我知道获取当前位置是一个异步过程,所以我也尝试在正文部分使用FutureBuilder:
FutureBuilder<LocationData>(
future: currentLocation,
builder: (context, snapshot) {
if (snapshot.hasData) {
LocationData currentLocation = snapshot.data;
return GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(
currentLocation.latitude, currentLocation.longitude)),
myLocationEnabled: true,
);
} else if (snapshot.hasError) {
return (Text("${snapshot.error}"));
}
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.orangeAccent,
),
);
},
),
当我不得不从 http GET 请求中检索数据时,它的作用就像一个魅力,但这次它只会导致无穷无尽的CircularProgressIndicator。
我从堆栈问题尝试了许多其他解决方案,包括当currentLocation 为空时返回空Container,为FutureBuilder snapshot.connectionState 创建条件,同样没有成功。
有趣的是,当我深入研究Location.getCurrentLocation() 方法时,我发现:
/// Gets the current location of the user.
///
/// Throws an error if the app has no permission to access location.
/// Returns a [LocationData] object.
Future<LocationData> getLocation() async {
return LocationPlatform.instance.getLocation();
}
然后转到:
/// Gets the current location of the user.
///
/// Throws an error if the app has no permission to access location.
/// Returns a [LocationData] object.
Future<LocationData> getLocation() {
throw UnimplementedError();
}
这让我怀疑这个插件是否可以工作。
这是我的flutter doctor -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
【问题讨论】:
标签: android ios google-maps flutter location