10

I am developing a flutter app for web, and I am trying to execute a callback method when I scroll the mouse wheel inside a widget (which is not a scrolling widget).

I am aware of the MouseRegion widget, and using a Listener as its child I can detect onPointerSignal events. This works fine when the Listener's child is a scrollable widget, such a ListView, but it does not work if this widget is not scrollable.

What I ideally would like to have is a widget similar to GestureDetector, with callback methods that are similar to onPanStart, onPanUpdate and onPanEnd, but instead happening on mouse wheel events (or, in the same way, for trackpad scrolling events on laptops).

Anybody knows how can I achieve this?

1 Answer 1

12

Listener does not need any parent. A widget like the following can be used, which wraps its child in a Listener and calls the given callback when a PointerScrollEvent is received:

class ScrollDetector extends StatelessWidget {
  final void Function(PointerScrollEvent event) onPointerScroll;
  final Widget child;

  const ScrollDetector({
    Key key,
    @required this.onPointerScroll,
    @required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerSignal: (pointerSignal) {
        if (pointerSignal is PointerScrollEvent) onPointerScroll(pointerSignal);
      },
      child: child,
    );
  }
}

Here's a complete example on DartPad.

Sign up to request clarification or add additional context in comments.

4 Comments

your code works perfectly. However in the DartPad example you provided, if I omit the color: Colors.green line, it stops working. Why does it work only when a color is provided?
@DaniS. From the docs: By default, containers return false for all hit tests. If the color property is specified, the hit testing is handled by ColoredBox, which always returns true. If the decoration or foregroundDecoration properties are specified, hit testing is handled by Decoration.hitTest.
It looks like this will only work on widgets that listen to touch input.
I thought of a workaround for no scrolling over HTMLView by displaying a PointerInterceptor over the view when user scrolls, but, first, the listener doesn't work when the cursor is over the HTMLView which defies the purpose of this for me and second, it doesn't notify when the even stops/ends that even if the user had scrolled over any other component, the PointerInterceptor doesn't hide which makes the HtmlView unusable. It's sad that's none of the WYSIWYG editor works properly in Flutter web.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.