Flutter:在用户输入时显示标记信息窗口抛出 PlatformException
Posted
技术标签:
【中文标题】Flutter:在用户输入时显示标记信息窗口抛出 PlatformException【英文标题】:Flutter: display Marker information window upon user's input throws PlatformException 【发布时间】:2021-04-21 00:28:22 【问题描述】:我正在实现这个应用程序,用户可以在其中插入他们的街道地址和城市,并且该位置将显示在地图上。我正在使用Google Maps package 来显示地图。
我想要的行为是,当用户提交位置时 - 地图将聚焦在提交的位置上,Marker
将与其InfoWindow
一起显示。
我试图实现它,但由于某种原因,我的代码总是抛出异常(下面标有FIXME:
的有问题的代码行):
E/flutter (23235): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: PlatformException(Invalid markerId, showInfoWindow called with invalid markerId, null, null)
在线查找问题并没有产生任何结果。有人遇到过这样的问题吗?
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
intl: ^0.16.1
provider: ^4.3.2+2
google_fonts: ^1.1.1
cupertino_icons: ^1.0.0
collection: ^1.14.13
cached_network_image: ^2.5.0
fluttertoast: ^7.1.6
shared_preferences: ^0.5.12+4
flutter_staggered_animations: "^0.1.2"
badges: ^1.1.6
google_maps_flutter: ^1.1.1
location: ^3.0.0
geocoder: ^0.2.1
我的代码:
final TextEditingController _googleStreetController = TextEditingController();
final TextEditingController _googleCityController = TextEditingController();
final FocusNode _googleStreetInputFocusNode = FocusNode();
final FocusNode _googleCityInputFocusNode = FocusNode();
/// Google Map controller
Completer<GoogleMapController> _googleMapsController = Completer();
/// initial camera position of the map - set to 5th avenue, NYC
static const LatLng _center = const LatLng(40.75476210819693, -73.98163492275201);
/// set of map markers that user inserted
final Set<Marker> _markers = ;
/// method that is called on map creation and takes a MapController as a parameter.
Future<void> _onMapCreated(GoogleMapController controller) async
setState(()
_googleMapsController.complete(controller);
);
if(_markers.isEmpty)
return;
var marker = _markers.first;
double lat = marker.position.latitude;
double long = marker.position.longitude;
var c = await _googleMapsController.future;
await c.moveCamera(CameraUpdate.newLatLng(LatLng(lat, long)));
await c.showMarkerInfoWindow(marker.markerId);
setState(()
);
InputDecoration _getInputDecoration(String hint)
return InputDecoration(
enabledBorder: _getOutlineInputBorder(),
focusedBorder: _getOutlineInputBorder(color: Colors.lightGreen.shade800),
hintText: hint,
suffixIcon: hint == 'City'
? Icon(Icons.location_city_outlined)
: Icon(Icons.home_outlined),
contentPadding: EdgeInsets.fromLTRB(5.0 , 5.0 , 5.0 , 5.0),
);
OutlineInputBorder _getOutlineInputBorder(Color color = Colors.grey)
return OutlineInputBorder(
borderSide: BorderSide(
color: color,
width: 1.3,
),
borderRadius: BorderRadius.all(Radius.circular(30)),
);
bool _isAddressEmpty()
return _googleStreetController.text.isEmpty || _googleCityController.text.isEmpty;
///removing focus from all text field's
void _unfocusAll()
_googleCityInputFocusNode.unfocus();
_googleStreetInputFocusNode.unfocus();
@override
Widget build(BuildContext context)
return Material(
child: Center(
child: IconButton(
iconSize: 27.0, ///<-- default is 24.0
icon: Icon(Icons.favorite),
onPressed: ()
showDialog(
context: context,
barrierDismissible: true,
builder: (context)
return Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: GestureDetector(
onTap: ()
FocusScope.of(context).unfocus();
,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
child: Material(
child: Container(
color: Colors.transparent,
height: MediaQuery.of(context).size.height * 0.8,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 5,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(
flex: 4,
child: Padding(
padding: const EdgeInsets.only(
left: 8.0,
right: 4.0,
top: 12.0,
bottom: 9.0,
),
child: TextField(
controller: _googleStreetController,
decoration: _getInputDecoration('Street'),
style: GoogleFonts.lato(
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
focusNode: _googleStreetInputFocusNode,
autofocus: false,
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.center,
keyboardType: TextInputType.streetAddress,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[a-z A-Z 0-9 .]'))
],
),
),
),
Flexible(
flex: 3,
child: Padding(
padding: const EdgeInsets.only(
left: 4.0,
right: 4.0,
top: 12.0,
bottom: 9.0,
),
child: TextField(
controller: _googleCityController,
decoration: _getInputDecoration('City'),
style: GoogleFonts.lato(
fontWeight: FontWeight.w600,
fontSize: 16.0,
),
keyboardType: TextInputType.streetAddress,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp('[a-z A-Z .]'))
],
focusNode: _googleCityInputFocusNode,
autofocus: false,
textAlign: TextAlign.start,
textAlignVertical: TextAlignVertical.center,
),
),
),
Flexible(
flex: 1,
child: Padding(
padding: const EdgeInsets.only(bottom: 9.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Flexible(
flex: 2,
child: IconButton(
icon: Icon(
Icons.add_location_alt,
color: Colors.deepOrange,
size: 27.0,
),
onPressed: () async
_unfocusAll();
if(_isAddressEmpty())
Fluttertoast.showToast(
msg: 'Please choose address'
);
return;
List<Address> locations = <Address>[];
try
locations = await Geocoder.local.findAddressesFromQuery(
_googleStreetController.text.trim() + ' ' + _googleCityController.text.trim()
);
on PlatformException catch (_)
Fluttertoast.showToast(
msg: 'Invalid address'
);
return;
if(locations.isEmpty)
Fluttertoast.showToast(
msg: 'Invalid address'
);
return;
var first = locations.first;
// print('$first.locality');
// print('$first.adminArea');
// print('$first.subLocality');
// print('$first.subAdminArea');
// print('$first.addressLine');
// print(' $first.thoroughfare');
// print('$first.subThoroughfare');
var coordinates = LatLng(first.coordinates.latitude, first.coordinates.longitude);
_markers.clear();
setState(()
_markers.add(
new Marker(
markerId: MarkerId(coordinates.toString()),
draggable: false,
visible: true,
position: coordinates,
icon: BitmapDescriptor.defaultMarker,
infoWindow: InfoWindow(
title: first.thoroughfare + ' ' + (first?.subThoroughfare ?? ''),
snippet: first.locality + ', ' + first.adminArea + ', ' + first.countryName,
)
)
);
);
var marker = _markers.first;
print(marker.toString());
print(marker.markerId);
double lat = marker.position.latitude;
double long = marker.position.longitude;
var c = await _googleMapsController.future;
await c.moveCamera(CameraUpdate.newLatLng(LatLng(lat, long)));
///FIXME: throwing unsupported exception
await c.showMarkerInfoWindow(marker.markerId);
setState(() );
),
),
Flexible(
flex: 1,
child: Text('Add',
style: GoogleFonts.lato(
fontSize: MediaQuery.of(context).size.height * 0.0256 * (12/18) + 0.4,
fontWeight: FontWeight.w600
),
),
),
],
),
)
),
],
),
),
Flexible(
flex: 33,
child: GoogleMap(
markers: _markers,
onTap: (LatLng details)
_unfocusAll();
,
onMapCreated: (c) async
await _onMapCreated(c);
,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 15.0,
),
),
),
Flexible(
flex: 4,
child: Center(
child: OutlineButton.icon(
onPressed: ()
if(_isAddressEmpty())
Fluttertoast.showToast(
msg: 'Please choose address'
);
return;
,
icon: Icon(
Icons.map,
color: Colors.black,
size: MediaQuery.of(context).size.height * 0.0256 * 25/18,
),
label: Text(
'Submit chosen location',
textAlign: TextAlign.center,
style: GoogleFonts.lato(
fontSize: MediaQuery.of(context).size.height * 0.0256 * 16/18,
fontWeight: FontWeight.w600,
),
),
borderSide: BorderSide(
color: Colors.black,
width: 1.5,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
),
),
)
],
),
),
),
),
),
),
);
);
)
)
);
@override
void dispose()
_googleCityInputFocusNode.dispose();
_googleStreetInputFocusNode.dispose();
_googleCityController.dispose();
_googleStreetController.dispose();
super.dispose();
【问题讨论】:
亲爱的AK-23,你能找到解决这个问题的办法吗? 【参考方案1】:替换
markerId: MarkerId(coordinates.toString()),
与
markerId: MarkerId("$coordinates.latitude"),
它将解决您的问题。
【讨论】:
很遗憾,出现同样的错误异常。 这个问题有什么解决办法吗?以上是关于Flutter:在用户输入时显示标记信息窗口抛出 PlatformException的主要内容,如果未能解决你的问题,请参考以下文章
命令行输入窗口用mysqldump备份时显示can't connect to mysql server on"localhost"when trying connect
Flutter HTTP 响应在 Flutter web 上测试时显示完整响应,但在 Android 设备上测试时显示不完整