I am using flutter_map to show some GeoJSON polygon layers and things work nicely. I am wondering how their properties can be displayed as popup knowing that polygons can be clickable and properties can be retrieved as follows:
void _onPolygonGeoJsonHit() {
final hitResult = polygonGeoJsonHitNotifier.value;
if (hitResult != null) {
final tappedPolygon = hitResult.hitValues;
debugPrint('Tapped polygon GeoJSON show all properties as follows: $tappedPolygon');
}
}
So far, these properties (in GeoJSON style) appear in the debug console after clicking on polygons:
How can these properties be shown in the screen as, for instance, an alert dialog or snackbar? is it possible this way or there is a smarter/better way to achieve this?
Thanks for the help,
**** UPDATE #1 ****
Following @Frank van Puffelen suggestion and some posts, I came up with:
void showSnackBar(BuildContext context) {
final snackBar = SnackBar(content: Text('Hi, it works!'));
_messengerKey.currentState!.showSnackBar(snackBar);
}
The question now is how can info stored in the tappedPolygon
inside the onPolygonGeoJsonHit()
function be passed to the showSnackBar
function? From readings I understand that they are void functions and the only result from them is null
, I still don't get how to use Future <String>
and/or async
to circumvent this (in case that's the right way to do it?).
Any help is welcomed,
**** UPDATE #2 ****
Thanks to @Frank, now the SnackBar
is getting something else than the default Hi, it works!
message I used as example, now it says Closure: () => void from Function '_onPolygonGeoJsonHit@28134734':.
:
This is what I did:
final hitResult = "some text";
void _onPolygonGeoJsonHit() {
setState(() {
final hitResult = polygonGeoJsonHitNotifier.value?.hitValues.toString();
if (result != null) {
final origString = hitResult;
final parts = origString.split(',');
debugPrint('=================================');
debugPrint('$parts');
debugPrint('=================================');
} else {
debugPrint('No hit detected.');
}
});
}
void showSnackBar(BuildContext context) {
//final snackBar = SnackBar(content: Text('Hi, it works!'));
final snackBar = SnackBar(
content: Text(
'$_onPolygonGeoJsonHit',
style: TextStyle(
color: Colors.black,
),
),
backgroundColor: Colors.white,
behavior: SnackBarBehavior.floating,
width: MediaQuery.sizeOf(context).width * 0.9,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
);
_messengerKey.currentState!.showSnackBar(snackBar);
}
What am I doing wrong here? I tried to call result
instead of '$_onPolygonGeoJsonHit'
but no luck. Also, adding result
in setState(result)
does not allow to call result
inside the SnackBar
.
After the extensive comments and updates, it's clear that the question is:
How can I use the JSON value that I have in the callback in a place where I can display (it in the UI) in a snackbar?
This is very common question for Flutter, and in your case the easiest answer is to:
store the value in your _AnAppState
class _AnAppState extends State<AnApp> {
String jsonMessage = ""; // 👈 initial value is an empty string
// for data query
...
set that value in the callback, inside a setState
void _onPolygonGeoJsonHit() {
final hitResult = polygonGeoJsonHitNotifier.value;
if (hitResult != null) {
final tappedPolygon = hitResult.hitValues;
// 👇 Set the new value, and tell Flutter to repain
setState(() {
jsonMessage = polygonGeoJsonHitNotifier.value?.hitValues.toString()
});
...
use the value in the UI build
method to display the snackbar
@override
Widget build(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(jsonMessage))); // 👈
...