将经纬度传递给 Latlng 时出错
Error when passing latitude and longitude to Latlng in flutter
我正在尝试重构我的代码并将 showMap class 分离到一个新的 dart 文件中。我正在将调用此 class 的屏幕上的纬度和经度传递给 showMap。我检查过这里的纬度和经度不为空。但我收到一条错误消息:
The following NoSuchMethodError was thrown building showMap(dirty): The method 'compareTo' was called on null. Receiver: null Tried calling: compareTo(-90.0)
class showMap extends StatelessWidget {
showMap({this.latitude, this.longitude});
double latitude;
double longitude;
@override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(latitude, longitude), // The Error line
zoom: 16.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']),
MarkerLayerOptions(
markers: [
Marker(
width: 80.0,
height: 80.0,
point: LatLng(58.7041, 37.1025),
builder: (ctx) => GestureDetector(
child: Container(
child: Icon(
Icons.location_on,
size: 60,
color: Color(0xFF744D81),
),
),
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) {
return MarkerPopup();
});
},
),
),
Marker(
width: 80.0,
height: 80.0,
point: LatLng(58.4419, 37.0784),
builder: (ctx) => GestureDetector(
child: Container(
child: Icon(Icons.location_on,
size: 60, color: Color(0xFF744D81)),
),
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) {
return MarkerPopup();
});
},
),
),
],
),
],
);
}
}
这是调用 showMap 的代码部分:
class _HomePageState extends State<HomePage> {
void getLocation() async {
Location location = Location();
await location.getCurrrentLocation();
latitude = location.latitude;
longitude = location.longitude;
}
@override
void initState() {
super.initState();
getLocation();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Udan'),
backgroundColor: Color(0xFF4E295B),
centerTitle: true,
),
body: Stack(
children: <Widget>[
showMap(
latitude: latitude,
longitude: longitude,
),
],
),
);
}
}
奇怪的是,一两秒钟后,错误消失,地图加载到正确的中心。但与此同时,代码中断并且屏幕显示错误。我猜这是因为获取位置需要时间,并且在获取位置之前传递纬度和经度的空值。在为 showMap 赋值之前,我已经在原始屏幕中使用了 async await。我如何让它工作?谢谢
方法 getLocation 包含一个异步操作,构建方法在解析之前执行。
一个选项可以是在纬度和经度为空时显示加载程序。解决了未来 location.getCurrrentLocation 后,您可以调用 showMap.
showMap()
在任何位置数据存在之前被调用。您应该等待位置数据,然后使用数据构建地图。这可以使用 FutureBuilder
:
首先,你应该创造一个未来。
Future<Location> getLocation = Future<Location>() async {
Location location = new Location();
var serviceEnabled = await location.serviceEnabled();
if (!serviceEnabled) {
serviceEnabled = await location.requestService();
if (!serviceEnabled) {
return null;
}
}
var currentLocation = await location.getLocation();
return currentLocation;
}
然后 return 一个 FutureBuilder 代替 showMap():
FutureBuilder<Location>(
future: getLocation(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return showMap(latitude: snapshot.data.latitude, longitude: snapshot.data.longitude);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
});
我无法验证我的代码,因为我无法使位置包工作。如果您发现任何错误,我很乐意编辑我的答案。
我正在尝试重构我的代码并将 showMap class 分离到一个新的 dart 文件中。我正在将调用此 class 的屏幕上的纬度和经度传递给 showMap。我检查过这里的纬度和经度不为空。但我收到一条错误消息:
The following NoSuchMethodError was thrown building showMap(dirty): The method 'compareTo' was called on null. Receiver: null Tried calling: compareTo(-90.0)
class showMap extends StatelessWidget {
showMap({this.latitude, this.longitude});
double latitude;
double longitude;
@override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(latitude, longitude), // The Error line
zoom: 16.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']),
MarkerLayerOptions(
markers: [
Marker(
width: 80.0,
height: 80.0,
point: LatLng(58.7041, 37.1025),
builder: (ctx) => GestureDetector(
child: Container(
child: Icon(
Icons.location_on,
size: 60,
color: Color(0xFF744D81),
),
),
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) {
return MarkerPopup();
});
},
),
),
Marker(
width: 80.0,
height: 80.0,
point: LatLng(58.4419, 37.0784),
builder: (ctx) => GestureDetector(
child: Container(
child: Icon(Icons.location_on,
size: 60, color: Color(0xFF744D81)),
),
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) {
return MarkerPopup();
});
},
),
),
],
),
],
);
}
}
这是调用 showMap 的代码部分:
class _HomePageState extends State<HomePage> {
void getLocation() async {
Location location = Location();
await location.getCurrrentLocation();
latitude = location.latitude;
longitude = location.longitude;
}
@override
void initState() {
super.initState();
getLocation();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Udan'),
backgroundColor: Color(0xFF4E295B),
centerTitle: true,
),
body: Stack(
children: <Widget>[
showMap(
latitude: latitude,
longitude: longitude,
),
],
),
);
}
}
奇怪的是,一两秒钟后,错误消失,地图加载到正确的中心。但与此同时,代码中断并且屏幕显示错误。我猜这是因为获取位置需要时间,并且在获取位置之前传递纬度和经度的空值。在为 showMap 赋值之前,我已经在原始屏幕中使用了 async await。我如何让它工作?谢谢
方法 getLocation 包含一个异步操作,构建方法在解析之前执行。
一个选项可以是在纬度和经度为空时显示加载程序。解决了未来 location.getCurrrentLocation 后,您可以调用 showMap.
showMap()
在任何位置数据存在之前被调用。您应该等待位置数据,然后使用数据构建地图。这可以使用 FutureBuilder
:
首先,你应该创造一个未来。
Future<Location> getLocation = Future<Location>() async {
Location location = new Location();
var serviceEnabled = await location.serviceEnabled();
if (!serviceEnabled) {
serviceEnabled = await location.requestService();
if (!serviceEnabled) {
return null;
}
}
var currentLocation = await location.getLocation();
return currentLocation;
}
然后 return 一个 FutureBuilder 代替 showMap():
FutureBuilder<Location>(
future: getLocation(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return showMap(latitude: snapshot.data.latitude, longitude: snapshot.data.longitude);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
});
我无法验证我的代码,因为我无法使位置包工作。如果您发现任何错误,我很乐意编辑我的答案。