pointer_interceptor: ^0.9.0+1 copied to clipboard
A widget to prevent clicks from being swallowed by underlying HtmlElementViews on the web.
PointerInterceptor is a widget that prevents mouse events (in web) from being captured by an underlying
You can use this widget in a cross-platform app freely. In mobile, where the issue that this plugin fixes does not exist, the widget acts as a pass-through of its
children, without adding anything to the render tree.
What is the problem? #
When overlaying Flutter widgets on top of
HtmlElementView widgets that respond to mouse gestures (handle clicks, for example), the clicks will be consumed by the
HtmlElementView, and not relayed to Flutter.
The result is that Flutter widget's
onTap (and other) handlers won't fire as expected, but they'll affect the underlying webview.
|In the dashed areas, mouse events won't work as expected. The |
How does this work? #
PointerInterceptor creates a platform view consisting of an empty HTML element. The element has the size of its
child widget, and is inserted in the layer tree behind its child in paint order.
This empty platform view doesn't do anything with mouse events, other than preventing them from reaching other platform views underneath it.
This gives an opportunity to the Flutter framework to handle the click, as expected:
How to use #
Some common scenarios where this widget may come in handy:
- FAB unclickable in an app that renders a full-screen background Map
- Custom Play/Pause buttons on top of a video element don't work
- Drawer contents not interactive when it overlaps an iframe element
All the cases above have in common that they attempt to render Flutter widgets on top of platform views that handle pointer events.
There's two ways that the
PointerInterceptor widget can be used to solve the problems above:
Wrapping your button element directly (FAB, Custom Play/Pause button...):
PointerInterceptor( child: ElevatedButton(...), )
As a root container for a "layout" element, wrapping a bunch of other elements (like a Drawer):
Scaffold( ... drawer: PointerInterceptor( child: Drawer( child: ... ), ), ... )
PointerInterceptor widget has a
debug property, that will render it visibly on the screen (similar to the images above).
This may be useful to see what the widget is actually covering when used as a layout element.