DetectScroll constructor

const DetectScroll({
  1. Key? key,
  2. required Widget child,
  3. void onChange({
    1. required bool canScroll,
    2. required double scrollbarWidth,
    })?,
  4. bool cancelNotificationBubbling = false,
})

The DetectScroll can detect if the content of a Scrollable is larger than the Scrollable itself, which means that the content can be scrolled, and that a scrollbar is likely visible. It can also tell you the probable width of that scrollbar.

This is useful for positioning widgets relative to the scrollbar, so that the scrollbar doesn't overlap them. This can be important when the scrollbar is permanently visible, usually on the Web and desktop.

Note that DetectScroll will only detect the scrolling of its closest scrollable descendant (a scrollable is a SingleChildScrollView, ListView, GridView etc). Usually, you'd wrap the scrollable you care about directly with a DetectScroll. For example:

DetectScroll(
 child: SingleChildScrollView(
    child: Column( ...
 ...
);

To get the current scroll state and the scrollbar width, descendants can call:

bool canScroll = DetectScroll.of(context).canScroll;
double width = DetectScroll.of(context).scrollbarWidth;

For example, suppose you want to add a help button to the top-right corner of a scrollable, and account for the scrollbar width only if it's visible:

bool canScroll = DetectScroll.of(context).canScroll;
double width = DetectScroll.of(context).scrollbarWidth;

return Stack(
  children: [
     child,
     Positioned(
        right: canScroll ? width : 0,
        top: 0,
        child: HelpButton(),
     ),
  ],
);

Another alternative is using the onChange callback:

DetectScroll(
   onChange: ({
      required bool canScroll,
      required double width,
   }) {
      // Do something.
   }
   child: ...
),

In more detail:

The DetectScroll actually only detects if its subtree can scroll, in other words, that its closest descendant Scrollable has enough content so that not all of it fits the available visible space, and then informs its descendants about this fact.

Note this doesn't mean there is actually a scrollbar visible, but only that the content can be scrolled. For this reason, you should use it to detect scrollbars only when a scrollbar is always shown when the content doesn't fit (like on the web or desktop), or when you're using a custom scrollbar that is always visible.

Regarding the width of the scrollbar provided by DetectScroll, this information is calculated from the current theme at the DetectScroll. For this reason, if you use this width, make sure the scrollbar is actually using this same theme.

Implementation

const DetectScroll({
  Key? key,
  required this.child,
  this.onChange,
  this.cancelNotificationBubbling = false,
}) : super(key: key);