ScrollController class

Controls a scrollable widget.

Scroll controllers are typically stored as member variables in State objects and are reused in each A single scroll controller can be used to control multiple scrollable widgets, but some operations, such as reading the scroll offset, require the controller to be used with a single scrollable widget.

A scroll controller creates a ScrollPosition to manage the state specific to an individual Scrollable widget. To use a custom ScrollPosition, subclass ScrollController and override createScrollPosition.

Accessing Scrolling Information

There are several ways to acquire information about scrolling and scrollable widgets, but each provides different types of information about the scrolling activity, the position, and the dimensions of the Viewport.

A ScrollController is a Listenable. It notifies its listeners whenever any of the attached ScrollPositions notify their listeners, such as when scrolling occurs. This is very similar to using a NotificationListener of type ScrollNotification to listen to changes in the scroll position, with the difference being that a notification listener will provide information about the scrolling activity. A notification listener can further listen to specific subclasses of ScrollNotification, like UserScrollNotification.

This sample shows the difference between using a ScrollController or a NotificationListener of type ScrollNotification to listen to scrolling activities. Toggling the Radio button switches between the two. Using a ScrollNotification will provide details about the scrolling activity, along with the metrics of the ScrollPosition, but not the scroll position object itself. By listening with a ScrollController, the position object is directly accessible. Both of these types of notifications are only triggered by scrolling.

To create a local project with this code sample, run:
flutter create --sample=cupertino.ScrollPosition.1 mysample

ScrollController does not notify its listeners when the list of ScrollPositions attached to the scroll controller changes. To listen to the attaching and detaching of scroll positions to the controller, use the ScrollController.onAttach and ScrollController.onDetach methods. This is also useful for adding a listener to the ScrollPosition.isScrollingNotifier when the position is created during the build method of the Scrollable.

At the time that a scroll position is attached, the ScrollMetrics, such as the ScrollMetrics.maxScrollExtent, are not yet available. These are not determined until the Scrollable has finished laying out its contents and computing things like the full extent of that content. ScrollPosition.hasContentDimensions can be used to know when the metrics are available, or a ScrollMetricsNotification can be used, discussed further below.

This sample shows how to apply a listener to the ScrollPosition.isScrollingNotifier using ScrollController.onAttach. This is used to change the AppBar's color when scrolling is occurring.

To create a local project with this code sample, run:
flutter create --sample=cupertino.ScrollPosition.2 mysample

From a different context

When needing to access scrolling information from a context that is within the scrolling widget itself, use Scrollable.of to access the ScrollableState and the ScrollableState.position. This would be the same ScrollPosition attached to a ScrollController.

When needing to access scrolling information from a context that is not an ancestor of the scrolling widget, use ScrollNotificationObserver. This is used by AppBar to create the scrolled under effect. Since Scaffold.appBar is a separate subtree from the Scaffold.body, scroll notifications would not bubble up to the app bar. Use ScrollNotificationObserverState.addListener to listen to scroll notifications happening outside of the current context.

Dimension changes

Lastly, listening to a ScrollController or a ScrollPosition will not notify when the ScrollMetrics of a given scroll position changes, such as when the window is resized, changing the dimensions of the Viewport and the previously mentioned extents of the scrollable. In order to listen to changes in scroll metrics, use a NotificationListener of type ScrollMetricsNotification. This type of notification differs from ScrollNotification, as it is not associated with the activity of scrolling, but rather the dimensions of the scrollable area, such as the window size.

This sample shows how a ScrollMetricsNotification is dispatched when the windowSize is changed. Press the floating action button to increase the scrollable window's size.

To create a local project with this code sample, run:
flutter create --sample=cupertino.ScrollPosition.3 mysample

Typically used with ListView, GridView, CustomScrollView.

See also:



ScrollController({double initialScrollOffset = 0.0, bool keepScrollOffset = true, String? debugLabel, ScrollControllerCallback? onAttach, ScrollControllerCallback? onDetach})
Creates a controller for a scrollable widget.


debugLabel String?
A label that is used in the toString output. Intended to aid with identifying scroll controller instances in debug output.
hasClients bool
Whether any ScrollPosition objects have attached themselves to the ScrollController using the attach method.
no setter
hashCode int
The hash code for this object.
no setterinherited
hasListeners bool
Whether any listeners are currently registered.
no setterinherited
initialScrollOffset double
The initial value to use for offset.
no setter
keepScrollOffset bool
Each time a scroll completes, save the current scroll offset with PageStorage and restore it if this controller's scrollable is recreated.
offset double
The current scroll offset of the scrollable widget.
no setter
onAttach ScrollControllerCallback?
Called when a ScrollPosition is attached to the scroll controller.
onDetach ScrollControllerCallback?
Called when a ScrollPosition is detached from the scroll controller.
position ScrollPosition
Returns the attached ScrollPosition, from which the actual scroll offset of the ScrollView can be obtained.
no setter
positions Iterable<ScrollPosition>
The currently attached positions.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited


addListener(VoidCallback listener) → void
Register a closure to be called when the object changes.
animateTo(double offset, {required Duration duration, required Curve curve}) Future<void>
Animates the position from its current value to the given value.
attach(ScrollPosition position) → void
Register the given position with this controller.
createScrollPosition(ScrollPhysics physics, ScrollContext context, ScrollPosition? oldPosition) ScrollPosition
Creates a ScrollPosition for use by a Scrollable widget.
debugFillDescription(List<String> description) → void
Add additional information to the given description for use by toString.
detach(ScrollPosition position) → void
Unregister the given position with this controller.
dispose() → void
Discards any resources used by the object. After this is called, the object is not in a usable state and should be discarded (calls to addListener will throw after the object is disposed).
jumpTo(double value) → void
Jumps the scroll position from its current value to the given value, without animation, and without checking if the new value is in range.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
notifyListeners() → void
Call all the registered listeners.
removeListener(VoidCallback listener) → void
Remove a previously registered closure from the list of closures that are notified when the object changes.
toString() String
A string representation of this object.


operator ==(Object other) bool
The equality operator.