'Removing OverLayEntry on Back button in Flutter

I am using OverlayEntry and I want entry to remove on Back Press.

OverlayEntry overlayEntry;
    overlayEntry = OverlayEntry(builder: (c) {
      return FullScreenLoader(
          loaderText: "Placing Order",
          );
    },maintainState: true);
    Overlay.of(context).insert(overlayEntry);

and Inside FullScreenLoader Build method I have used onWillScope but still it is not working.

 @override
  Widget build(BuildContext context) {
    return new WillPopScope(
        onWillPop: _onWillPop,
    );
  }

Future<bool> _onWillPop() {
    return "" ?? false;
}

I just want to detect physical back press button so that I can remove the overlay on Back Press.

AM I missing something? Or it is not possible with overLay?



Solution 1:[1]

The way you try it should work. Use WillPopScope to detect the back press and remove the overlay if it is visible.

Here is a working sample code. Keep a global reference to the overlay entry and add the WillPopScope in the build method of the state class:

class _XYZState extends State<XYZ> {
  OverlayEntry _detailsOverlayEntry;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: WillPopScope(
        onWillPop: _onWillPop,
        child: GoogleMap(
          mapType: MapType.normal,
          initialCameraPosition: _kFallbackInitialCameraPosition,
          polylines: _polylines.toSet(),
          myLocationEnabled: false,
          myLocationButtonEnabled: false,
          onMapCreated: (GoogleMapController controller) {
            _controller.complete(controller);
          },
        ),
      ),
    );
  }

  Future<bool> _onWillPop() {
    if(_detailsOverlayEntry != null){
      _detailsOverlayEntry.remove();
      _detailsOverlayEntry = null;
      return Future.value(false);
    }
    return Future.value(true);
  }
}

Like you can see, the _detailsOverlayEntry == null condition check is used to check whether the overlay entry is visible. In case it is visible, remove it and set the reference to null.

The next time back is pressed, it will pop the route.

Solution 2:[2]

I know this post is older. But I had a similar problem. In my case I didn't want the underlying page to pop but only the overlay. I achieved this by using BackButtonListener.

class DismissibleOverlay extends StatelessWidget {
  final Widget child;
  final OverlayEntry overlayEntry;
  const DismissibleOverlay({Key? key, required this.child, required this.overlayEntry}) : super(key: key);



  @override
  Widget build(BuildContext context) {
    return BackButtonListener(
        onBackButtonPressed: () async { overlayEntry.remove(); return Future.value(true);},
        child: Dismissible(
            onDismissed: (dismissDirection) => overlayEntry.remove(),
            direction: DismissDirection.vertical,
            key: Key(''),
            child: ColorfulSafeArea(child: child)
        )
    );

  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adrian
Solution 2 CKWDani