Handling click event between 2 stacked widgets in flutter

101 views Asked by At

I currently have an open street map widget (in flutter) in which I display markers which when I click on them display a panel with informations on it. The problem is that even when the panel is displayed, the click priority is still sent to the map (which is behind the panel). I already tried a gesturedetector on the panel, ways to disable the map but it seems osm is way less permissible than google maps.

If u have any idea...

As I said, I already tried a gesturedetector on the panel, multiple ways to disable the map when the panel is displayed but it doesn't work ... I just want the panel to manage click gestion because actually when I click on the panel, it's the map that receives it.

Thank you

The panel :

Widget _panel(ScrollController sc) {
    return AbsorbPointer(
      absorbing: isPanelOpen,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
        },
        child: Container(
          color: beige,
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  IconButton(
                    icon: const Icon(Icons.close),
                    onPressed: () {
                      _panelController.close();
                    },
                  ),
                ],
              ),
              if (selectedMarker != null)
                Row(
                  children: [
                    Text(
                      selectedMarker!.shopName,
                      style: const TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.bold, ....

The build method

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SlidingUpPanel(
        controller: _panelController,
        minHeight: isPanelOpen ? 50 : 0,
        maxHeight: MediaQuery.of(context).size.height * 0.9,
        panelBuilder: (sc) => _panel(sc),
        isDraggable: true,
        body: Stack(
          children: [
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: PreferredSize(
                preferredSize: const Size.fromHeight(50),
                child: AppBar(
                  backgroundColor: Colors.white,
                  elevation: 0,
                  title: Container(
                    width: MediaQuery.of(context).size.width / 3,
                    padding: const EdgeInsets.all(8.0),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    child: Row(
                      children: [
                        const Icon(
                          Icons.search,
                          color: Colors.black54,
                        ),
                        const SizedBox(width: 8.0),
                        Expanded(
                          child: TextField(
                            controller: searchController,
                            decoration: const InputDecoration(
                              hintText: 'Rechercher...',
                              border: InputBorder.none,
                              hintStyle: TextStyle(color: Colors.black54),
                            ),
                          ),
                        ),
                        IconButton(
                          icon: const Icon(Icons.tune),
                          onPressed: () {
                            Navigator.of(context).push(
                              MaterialPageRoute(
                                builder: (context) => const MapFiltersState(),
                              ),
                            );
                          },
                        )
                      ],
                    ),
                  ),
                ),
              ),
            ),
            Positioned(
              top: 50,
              bottom: 0,
              left: 0,
              right: 0,
              child: Container(
                clipBehavior: Clip.antiAlias,
                decoration: const BoxDecoration(
                  color: Color(0xFFFFFBE2),
                ),
                child: OSMFlutter(
                  controller: controller,
                  onGeoPointClicked: (geoPoint) {
                    _checkMarkerTap(geoPoint);
                  },
                  osmOption: OSMOption(
                    showDefaultInfoWindow: false,
                    userTrackingOption: const UserTrackingOption(
                      enableTracking: true,
                      unFollowUser: true,
                    ),
                    zoomOption: const ZoomOption(
                      initZoom: 15,
                      minZoomLevel: 3,
                      maxZoomLevel: 19,
                      stepZoom: 1.0,
                    ),
                    userLocationMarker: UserLocationMaker(
                      personMarker: const MarkerIcon(
                        icon: Icon(
                          Icons.location_history_rounded,
                          color: Colors.red,
                          size: 48,
                        ),
                      ),
                      directionArrowMarker: const MarkerIcon(
                        icon: Icon(
                          Icons.double_arrow,
                          size: 48,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

The way I display the panel

void _checkMarkerTap(GeoPoint tapLocation) {
    for (MyCustomMarker marker in customMarkers) {
      double distance = calculateDistance(
        tapLocation.latitude,
        tapLocation.longitude,
        marker.latitude,
        marker.longitude,
      );

      if (distance < 50) {
        print("Marker tapped: ${marker.shopName}");
        setState(() {
          selectedMarker = marker;
          isPanelOpen = true;
        });
        _panelController.open();
      }
    }
  }
0

There are 0 answers