Adding and Customizing a Scrollbar in Flutter

Last updated on April 29, 2021 The Plumber Loading... 2 comments

In Flutter, scrollable widgets (ListView, GridView, etc) have no scrollbar by default. A scrollbar shows a user how long a view is. It indicates how far the user has scrolled from the top boundary and lets him or her quickly jump to a particular point.

In this article, we’ll have a look at the Scrollbar widget in Flutter and learn how to style and customize it through a couple of different examples (the last one implements a CupertinoScrollbar).

Overview

The only required parameter of a Scrollbar is a child widget. Others are optinal.

ParameterTypeDescription
child (required)WidgetThe child widget of the Scrollbar (ListView, GridView, …)
thicknessdoubleThe thickness of the scrollbar
showTrackOnHoverboolDetermine whether the track will show on hover and remain, including during drag
controllerScrollControllerControls the Scrollbar dragging
hoverThicknessdoubleDetermine the thickness of the scrollbar when a hover state is active and showTrackOnHover is true
isAlwaysShownboolDetermine the scrollbar thumb will always remain visible or will fade out when it is not in use.
notificationPredicateScrollNotificationPredicateCheck whether a ScrollNotification should be handled by the Scrollbar
radiusRadiusSet the shape of the scrollbar thumb (rounded corners)

If the child widget of the Scrollbar has an infinite length (for example, when you use ListView.builder or GridView.builder without passing itemCount), the Scrollbar will not show up. However, there is no error message in this case.

Example 1: Basic Implementation

Preview:

The full code:

import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  // Dummy data
  final _myList = List.generate(50, (index) => 'Item $index');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Scrollbar(
        // I use a big thickness to make the thumb is easy to be seen
        // You should chose another number that makes more sense
        thickness: 10,
        isAlwaysShown: true,
        radius: Radius.circular(10), // give the thumb rounded corners
        child: ListView.builder(
          itemCount: _myList.length, // Don't forget this line
          itemBuilder: (context, index) => Card(
            key: ValueKey(_myList[index]),
            margin: EdgeInsets.all(15),
            elevation: 5,
            color: Colors.accents[Random().nextInt(Colors.accents.length)],
            child: ListTile(
              title: Text(
                _myList[index],
                style: TextStyle(fontSize: 24),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Example 2: Using scrollbarTheme

In this example, we’ll style the Scrollbar by using the ScrollbarThemeData class. Color, minimum thumb length, scrollbar margin, and much more are all set as we want.

Note: Since the Scrollbar dynamically changes to an iOS-style scrollbar on the iOS platform, using scrollbarTheme only makes effects on Android as you can see in the video below.

Preview:

The full code:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
          primarySwatch: Colors.green,
          scrollbarTheme: ScrollbarThemeData(
              isAlwaysShown: true,
              thickness: MaterialStateProperty.all(10),
              thumbColor: MaterialStateProperty.all(Colors.blue),
              radius: Radius.circular(10),
              minThumbLength: 100)),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  // Generating dummy data for testing purpose
  final List dummyData = List.generate(100, (index) => '$index');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Scrollbar(
        child: GridView.builder(
          itemCount: dummyData.length,
          gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 200,
              childAspectRatio: 3 / 2,
              crossAxisSpacing: 20,
              mainAxisSpacing: 20),
          itemBuilder: (context, index) {
            return GridTile(
                child: Container(
              color: Colors.amberAccent,
              alignment: Alignment.center,
              child: Text(
                dummyData[index],
                style: TextStyle(fontSize: 24),
              ),
            ));
          },
        ),
      ),
    );
  }
}

Example 3: Using CupertinoScrollbar

Using the CupertinoScrollbar widget is quite similar to using the Scrollbar widget. Don’t forget to import the cupertino library into your code:

import 'package:flutter/cupertino.dart';

Screenshot:

The full code:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  // Generating dummy data for testing purpose
  final List dummyData = List.generate(100, (index) => '$index');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: CupertinoScrollbar(
          thickness: 8,
          isAlwaysShown: true,
          child: ListView.builder(
            itemCount: dummyData.length,
            itemBuilder: (context, index) => Card(
              color: Colors.blue[200],
              child: Padding(
                padding: const EdgeInsets.all(30),
                child: Center(
                  child: Text(
                    dummyData[index],
                    style: TextStyle(fontSize: 30),
                  ),
                ),
              ),
            ),
          )),
    );
  }
}

Conclusion

We’ve explored a lot of things about the Scrollbar widget and walked over a few examples of using it in applications. If you’d like to learn more new and fascinating stuff in Flutter, take a look at the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples. Have a nice day and happy Fluttering.

Subscribe
Notify of
guest
2 Comments
Inline Feedbacks
View all comments
Rara
Rara
4 months ago

Nice article. It helps me a lot.

A Goodman
Admin
A Goodman
4 months ago
Reply to  Rara

Happy Fluttering

Related Articles