Scrollbar class

A Material Design scrollbar.

To add a scrollbar to a ScrollView, wrap the scroll view widget in a Scrollbar widget.

Learn more about Scrollbar on the Flutter YouTube channel.

For more information, see RawScrollbar.

Dynamically changes to a CupertinoScrollbar, an iOS style scrollbar, by default on the iOS platform.

The color of the Scrollbar thumb will change when WidgetState.dragged, or WidgetState.hovered on desktop and web platforms. These stateful color choices can be changed using ScrollbarThemeData.thumbColor.

This sample shows a Scrollbar that executes a fade animation as scrolling occurs. The Scrollbar will fade into view as the user scrolls, and fade out when scrolling stops.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [Scrollbar].

void main() => runApp(const ScrollbarExampleApp());

class ScrollbarExampleApp extends StatelessWidget {
  const ScrollbarExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Scrollbar Sample')),
        body: const ScrollbarExample(),
      ),
    );
  }
}

class ScrollbarExample extends StatelessWidget {
  const ScrollbarExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
      child: GridView.builder(
        primary: true,
        itemCount: 120,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
        ),
        itemBuilder: (BuildContext context, int index) {
          return Center(child: Text('item $index'));
        },
      ),
    );
  }
}

When thumbVisibility is true, the scrollbar thumb will remain visible without the fade animation. This requires that a ScrollController is provided to controller, or that the PrimaryScrollController is available.

When a ScrollView.scrollDirection is Axis.horizontal, it is recommended that the Scrollbar is always visible, since scrolling in the horizontal axis is less discoverable.

To see it in action, copy and run this code snippet on DartPad.

import 'package:material_ui/material_ui.dart';

/// Flutter code sample for [Scrollbar].

void main() => runApp(const ScrollbarExampleApp());

class ScrollbarExampleApp extends StatelessWidget {
  const ScrollbarExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Scrollbar Sample')),
        body: const ScrollbarExample(),
      ),
    );
  }
}

class ScrollbarExample extends StatefulWidget {
  const ScrollbarExample({super.key});

  @override
  State<ScrollbarExample> createState() => _ScrollbarExampleState();
}

class _ScrollbarExampleState extends State<ScrollbarExample> {
  final ScrollController _controllerOne = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scrollbar(
      controller: _controllerOne,
      thumbVisibility: true,
      child: GridView.builder(
        controller: _controllerOne,
        itemCount: 120,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
        ),
        itemBuilder: (BuildContext context, int index) {
          return Center(child: Text('item $index'));
        },
      ),
    );
  }
}

A scrollbar track can be added using trackVisibility. This can also be drawn when triggered by a hover event, or based on any WidgetState by using ScrollbarThemeData.trackVisibility.

The thickness of the track and scrollbar thumb can be changed dynamically in response to WidgetStates using ScrollbarThemeData.thickness.

See also:

  • RawScrollbar, a basic scrollbar that fades in and out, extended by this class to add more animations and behaviors.
  • ScrollbarTheme, which configures the Scrollbar's appearance.
  • CupertinoScrollbar, an iOS style scrollbar.
  • ListView, which displays a linear, scrollable list of children.
  • GridView, which displays a 2 dimensional, scrollable array of children.
Inheritance

Constructors

Scrollbar({Key? key, required Widget child, ScrollController? controller, bool? thumbVisibility, bool? trackVisibility, double? thickness, Radius? radius, ScrollNotificationPredicate? notificationPredicate, bool? interactive, ScrollbarOrientation? scrollbarOrientation})
Creates a Material Design scrollbar that by default will connect to the closest Scrollable descendant of child.
const

Properties

child Widget
The widget below this widget in the tree.
final
controller ScrollController?
The ScrollController used to implement Scrollbar dragging.
final
hashCode int
The hash code for this object.
no setterinherited
interactive bool?
Whether the Scrollbar should be interactive and respond to dragging on the thumb, or tapping in the track area.
final
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
notificationPredicate ScrollNotificationPredicate?
A check that specifies whether a ScrollNotification should be handled by this widget.
final
radius Radius?
The Radius of the scrollbar thumb's rounded rectangle corners.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
scrollbarOrientation ScrollbarOrientation?
Dictates the orientation of the scrollbar.
final
thickness double?
The thickness of the scrollbar in the cross axis of the scrollable.
final
thumbVisibility bool?
Indicates that the scrollbar thumb should be visible, even when a scroll is not underway.
final
trackVisibility bool?
Indicates that the scrollbar track should be visible.
final

Methods

build(BuildContext context) Widget
Describes the part of the user interface represented by this widget.
override
createElement() StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

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