Flutter: How to make a ListView transparent to pointer events (but not its non-transparent contents)?

Issue

I have a Scrollable (ListView or any other) and it contains a transparent widget, say Container(height:200). I can see through both the widget and the scrollable (in other words I can see the widgets behind the scrollable).

How can I be able to click through the transparent widget and the scrollable, so that I reach the widgets behind the scrollable?

ListView(
  children: [
    Container(height: 200), // Transparent.
    Container(color: Colors.red, height: 200),
    ],
);

Note, I cannot wrap the scrollable with IgnorePointer, because I still want to click the non-transparent widgets in the scrollable.

Solution

The only reasonable solution I can think of is to have a GestureDetector on the transparent container, which will give you the global position of the taps:

GestureDetector(
  onTapUp: (TapUpDetails tapUpDetails) {
    print("onTapUp global: " + tapUpDetails.globalPosition.toString());
  },

And then add a Key to the widget behind the list, and use it to get the global position of the top left corner of the widget’s rectangle, as well as the size of the widget, and use those to get the rectangle of the widget:

RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;

If the background widget does not move, you can do it within initState on the very next frame using WidgetsBinding.instance.addPostFrameCallback (the render object will be null if do it synchronously within initState) and save the Rect – otherwise you will have to recalculate it on every tap.

And then finally on each tap on the transparent container you can calculate whether the tap’s position is within the boundaries of the background widget, and invoke the corresponding code:

// if tap is within boundaries of the background widget
if (rectangle.contains(tapUpDetails.globalPosition)) {
  // your code here
}

Answered By – Ovidiu

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *