flutterflutter-animation

Sending debugPrint message to the screen


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:

enter image description here

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':.:

enter image description here

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.


Solution

  • 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:

    1. store the value in your _AnAppState

      class _AnAppState extends State<AnApp> {
        String jsonMessage = ""; // 👈 initial value is an empty string
        // for data query
        ...
      
    2. 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()
          });
          ...
      
    3. 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))); // 👈
        ...