[Flutter]google_maps_flutterでPlatformExceptionエラーの解決
Flutterに簡単にGoogle Mapを導入できるgoogle_maps_flutterというパッケージがあります。
自分はAndroidでこのパッケージを使っていたのですが、FlutterをiOS対応させてGoogle Mapを開いたら以下のエラーが出ました。Androidだけのときは出なかったのになんでや〜と思いながら手を動かしたら解決したので、その方法についてご説明します。
エラー
PlatformException(Invalid markerId, hideInfoWindow called with invalid markerId, null, null)
まずPlatformExceptionとは何か。PlatformException classのドキュメント1文目には以下とありますがよくわからん。
Flutterでプラットフォーム特有のAPIやプラグインを使用した場合、iOSやAndroidといったネイティブプラットフォーム側で出るエラーなのだと思います。
今回、iOSでgoogle_maps_flutterを使用した時発生したので、iOS側で何かしらエラーが出ていると捉えました。
エラー文のPlatformException()の中を見ると、Invalid markerId, hideInfoWindow called with invalid markerIdとあります。
markerIdとは、google_maps_flutterにmarkerId classがあり、Google Map上に表示するピン(marker)を識別するために必要となるIDのことです。
hideInfoWindowは、markerをタップしたら表示されるinfoWindowを非表示にするためにあり、GoogleMapController classのメソッドです。
infoWindowは、marker上部に表示されるウィンドウです。
自分は、画面をonTapした時にhideMarkerInfoWindowを呼び出してinfoWindowを非表示にできるようにしておりましたが、hideMarkerInfoWindow()に設定すべきmarkerIdを"marker"などと適当に設定していました。
GoogleMap(
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
padding: const EdgeInsets.only(bottom: 100),
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14.4746,
),
onTap: (LatLng latLng) {
mapController!.hideMarkerInfoWindow(
const MarkerId("marker"), ///here
);
},
myLocationEnabled: true,
myLocationButtonEnabled: true,
markers: markers,
),
Androidではこれで動いていたのですが、iOSでは許されなかったようで、ちゃんと設定したらエラーが解消しました。
@override
Widget build(BuildContext context) {
return Center(
child: StreamBuilder<QuerySnapshot>(
stream: stream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightGreenAccent,
),
);
}
final markers = _buildMarkers(snapshot.data!.docs);
return SafeArea(
child: Stack(children: [
GoogleMap(
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
padding: const EdgeInsets.only(bottom: 100),
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14.4746,
),
onTap: (LatLng latLng) {
for (var marker in markers) {
mapController!.hideMarkerInfoWindow(marker.markerId);
} //marker.markerIdへと変更
},
myLocationEnabled: true,
myLocationButtonEnabled: true,
markers: markers,
),
getDigitalCoinFromUsersFirestore(),
]),
);
},
),
);
}
}
Set<Marker> _buildMarkers(List<DocumentSnapshot> documents) {
return documents.map(
(DocumentSnapshot document) {
return Marker(
markerId: MarkerId(document.id),
position: LatLng(
document["position"]["geopoint"].latitude,
document["position"]["geopoint"].longitude,
),
onTap: () {
_showImageDialog(context, document);
},
infoWindow: InfoWindow(
title: "ユーザー名: ${document['username']}",
snippet: "コメント: ${document['comment']}",
),
);
},
).toSet();
}
自分はCloud firestoreにデータを保存しており、StreamBuilderでデータを取り出してGoogle Map上に表示するようにしています。
以下のコードにおいて、_buildMarkersメソッドに渡したmarkerIdのデータと同じmarkerIdをhideMarkerInfoWindowにも渡したらOKでした。
onTap: (LatLng latLng) {
for (var marker in markers) {
mapController!.hideMarkerInfoWindow(marker.markerId);
} //marker.markerIdへと変更
},
この記事が気に入ったらサポートをしてみませんか?