Preface:

This is the fourth day of my participation in the August More text Challenge. For details, see: August More Text Challenge. To prepare for the August challenge of the nuggets, I’m going to pick 31 components this month that haven’t been introduced before and do a full analysis and attribute introduction. These articles will be used as important material in the collection of the Flutter components. I hope I can stick to it, your support will be my biggest motivation ~

  • 1. [Flutter component collection] NotificationListener | August more text challenge
  • 2.【Flutter Components 】Dismissible | August more challenges
  • 3.【Flutter Component Collection 】 How the Switch was made | August More text Challenge
  • 4.【Flutter Component Collection 】Scrollbar | August more text challenge[this article]

1. Use of Scrollbar

1. Effect of the Scrollbar

In a slidable component like the ListView, by default there is no indicator on the right, making it difficult for the user to know the progress of the slide. Use the Scrollbar to bring up the slider on the right. The following is a look at how the Scrollbar looks on Android and iOS. You can see how the Scrollbar looks different on different platforms, such as rounded corners, height, width, etc. All of these can be found in the source code.

The Android platform The iOS platform

From a usage point of view, Scrollbar is very simple, just nested inside the ListView. And then when you slide, you have a scroll indicator, which looks pretty amazing. Here’s the magic: The ListView slides without any direct connection to the Scrollbar, and the Scrollbar slides after the ListView.

class ScrollbarDemo extends StatelessWidget {
  const ScrollbarDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scrollbar( //<--- tag1
      child: ListView(
          children:
              List.generate(
                60, (index) => ItemBox(index: index)).toList()), ); }}Copy the code

This pluggable combination allows for little coupling between components and allows one to change with the other. Scrollbar is simple to use, but the data notification scheme behind it is worth studying and learning.


2. Performance properties of the Scrollbar

As you can see from the constructor of the Scrollbar below, child is a required input and there are eight parameters. Let’s take a look at isAlwaysShown, thickness, and RADIUS, which determine the properties that the Scrollbar displays.

Scrollbar(
   isAlwaysShown: true.// Whether to always display
   radius: const Radius.circular(3), // Fillet radius
   thickness: 6./ / line widthchild: ... ) ;Copy the code

On the left-hand side below is the default display on The Android platform. You can see that the Scrollbar is only displayed during the slide process, and it appears and disappears with a transparent gradient animation. IsAlwaysShown indicates whether the Scrollbar is always displayed. Radius indicates the radius of a rounded corner. Thickness indicates the width of the Scrollbar slider.

Android displays by default This case shows that

3. Size area of the Scrollbar

All the components that can be displayed will take up particular positions in the area, and you can think about whether the Scrollbar size includes the entire ListView, is just a thin strip, or is just a small slider. As you can see from the layout viewer, the size of the Scrollbar is the entire mass, including the ListView. At this point, we can more or less guess how the Scrollbar source handles the layout.

guess The answer

4. Interactive

The following images show the effects of interactive:false and interactive:true. What it does is obvious: if true, the small slider can accept drag events to control the slide of the list. The default is false on mobile devices.

interactive:false interactive:true

5. Callback notification: notificationPredicate

NotificationPredicate is a callback function that calls the ScrollNotification object back to the consumer, and returns a bool to determine whether the Scrollbar is displayed.

@override
Widget build(BuildContext context) {
  return Scrollbar(
    notificationPredicate: _notificationPredicate,
    child: ListView(
        children:
            List.generate(60, (index) => ItemBox(index: index)).toList()),
  );
}

bool _notificationPredicate(ScrollNotification notification) {
  print('--$notification-- -- -- -- -- -- -- -- -- ');
  return true;
}
Copy the code

6. Slide controller: Controller

If you specify the controller property only for the ListView, then Scrollbar will report an error. You have to make sure they both have the same slide controller. With the slide controller we can listen to the list slide and control the slide.


In addition, the showTrackOnHover and hoverThickness properties, as the name implies, are hover effects, which are usually only available on non-mobile devices, and the ListView currently comes with a Scrollbar on the desktop by default.

At this point, all the properties of Scrollbar are covered. Here’s a quick look at the source code implementation of Scrollbar, not only so you know how to use it, but also a little bit of its internal mechanism, some of the logic processing in the source code, which may help you in some scenarios, it never hurts to know more. Know it, know its why, you grasp is fully.


Two, Scrollbar source code simple look

1. Scrollbar class definition

As you can see below, Scrollbar is a StatefulWidget that builds components with the _ScrollbarState state class.


Here is the full code for _ScrollbarState, by building CupertinoScrollbar if iOS, and _MaterialScrollbar otherwise.

This is the full source code for _ScrollbarState, but I don’t see the need for Scrollbar to be a StatefulWidget from here. I don’t know what you think.


2. Slide event listening and slider movement

CupertinoScrollbar and _MaterialScrollbar are both inherited from RawScrollbar, which means that their underlying logic is the same, but adapted to the platform.


As you can see in the RawScrollbarState build component code, a NotificationListener is used to listen for a ScrollNotification notification, executing the _handleScrollNotification method. If you are not familiar with the NotificationListener component, take a look at the first article


There’s some core logic in the _handleScrollNotification, where the notificationPredicate callback is fired first, and if the function returns false, This means that _handleScrollNotification returns false and the following logic will not be executed. This is why the slider does not display when false is returned. The next step is to perform a transparent gradient animation and update the scrollbarPainter based on notification information, which is the core of the process for the slider to slide along the list.


3. Drawing of slider

At the end of the RawScrollbarState#build method, you draw with the foregroundPainter, and the child is the ListView that is passed in. This is why the size area of the Scrollbar is an entire piece.

The drawing board is the ScrollbarPainter, which is created when the state is initialized.


ScrollbarPainter inherits from ChangeNotifier and implements CustomPainter, which means that it is both a visible and listening object and a drawing board, which means that it can notify the drawing board to be redrawn. Using ScrollbarPainter is declared as a member variable and performs updates itself when needed. This is also worth learning from, source code is the best teacher. As for the specific drawing logic, do not say, interested in their own see.

This is the end of this article. Thanks for watching. See you tomorrow