Always show scrollbar - Flutter
Asked Answered
F

7

42

I have a long text and I need to show the scrollbar by default when the user enters my page.

Currently, the bars not shown until the user click over the text and this, not good behavior because the user could leave the page without notice that there is some unread text.

My code:

    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(15.0),
        child: Center(
          child: Column(
            children: <Widget>[
              Image.asset(
                "assets/images/logo.png",
                height: 200.0,
              ),
              SizedBox(
                height: 40,
              ),
              Expanded(
                child: Scrollbar(
                  child: SingleChildScrollView(
                    child: Text("Long Text Here ...",
                      textDirection: TextDirection.rtl,
                      style: TextStyle(fontSize: 17.2),
                    ),
                  ),
                ),
              ),
              SizedBox(
                height: 50,
              ),
              Row(
                children: <Widget>[
                  Expanded(
                    child: RaisedButton(
                      child: Text("Continue"),
                      onPressed: () {
                        MaterialPageRoute route = MaterialPageRoute(
                            builder: (BuildContext context) => MainPage());
                        Navigator.of(context).push(route);
                      },
                    ),
                  ),
                  SizedBox(
                    width: 20.0,
                  ),
                  RaisedButton(
                    child: Text("Close"),
                    onPressed: () {
                      exit(0);
                    },
                  ),
                ],
              )
            ],
          ),
        ),
      ),
    );
  }```
Furtado answered 2/3, 2019 at 21:40 Comment(3)
I think Scrollbar does not have that feature,but I opened a issue about that topic : github.com/flutter/flutter/issues/28836Counterfactual
Here's an implementation of it that you can use: gist.github.com/slightfoot/beb74749bf2e743a6da294b37a7dcf8dRampant
@Rampant I get "a vertical viewport was given an unlimited amount of vertical space in which to expand" when using this custom widget. Even if I wrap it with Expanded and/or SizedBox.Boast
B
65

Updated Answer April 2023

As of v2.9.0-1.0.pre, isAlwaysShown is deprecated and you should use thumbVisibility instead. Check jayjw's more complete answer: https://mcmap.net/q/382774/-always-show-scrollbar-flutter


Original Answer June 2020

As of Flutter version 1.17, on Scrollbar you can set isAlwaysShown to true, but you must set the same controller for your Scrollbar and your SingleChildScrollView (and that applies to any other scrollable Widget as well).

Have in mind that, for the Scrollbar to be visible, there must be enough items to scroll. If there are not, the Scrollbar won't be shown.

Full working example:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyWidget(),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {  
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  final _scrollController = ScrollController();
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(15.0),
        child: Center(
          child: Column(
            children: <Widget>[
              // ...
              Expanded(
                child: Scrollbar(
                  controller: _scrollController, // <---- Here, the controller
                  isAlwaysShown: true, // <---- Required
                  child: SingleChildScrollView(
                    controller: _scrollController, // <---- Same as the Scrollbar controller
                    child: Text(
                      "Long Text Here ...",
                      textDirection: TextDirection.rtl,
                      style: TextStyle(fontSize: 17.2),
                    ),
                  ),
                ),
              ),
              // ...
            ],
          ),
        ),
      ),
    );
  }
}
Burra answered 2/6, 2020 at 20:15 Comment(9)
Check if you've defined the same controller for your Scrollbar and your scrollable Widget, and if you've set the isAlwaysShown to true in your ScrollbarBurra
that worked, when I added the controller to both the scrollbar and the SingleChildScrollView the scrollbars became visibleElyn
@Burra any idea why it would take me to scroll for the scrollbar to show up the first time, and then it stays up forever? I did put the controller in both spots, but the keyboard appearing (for a dialog using a singleChildScrollview) is what triggered the need for a scroll bar. Maybe that's related?Mackoff
@Eradicatore, there may be not enough items. Try adding a lot of items to your list and see if it shows the scrollbarBurra
@Burra the more I think about it I think it's related to my dialog not being a full stateful widget. Changes like this don't show up unless I pop and re-enter the dialog. I wish there was a simple way to do dialog updates. :(. Thanks again for sharing this method, it REALLY helped me in all the other places in my app! love itMackoff
@Mackoff if you use ScrollController, I suggest you turn your StatelessWidget into a StatefulWidget.Burra
For me it would show, but I couldn't grab it, even with controller assigned. Setting interactive: true, on the ScrollBar fixed that.Ombudsman
isAlwaysShown is deprecated and shouldn't be used. Use thumbVisibility instead. This feature was deprecated after v2.9.0-1.0.pre.Datura
MaterialStateProperty is deprecated. See answer here: https://mcmap.net/q/382774/-always-show-scrollbar-flutterFeast
E
22

As of v2.9.0-1.0, thumbVisiblity is the proper field to set.

Note you can set this globally for your app (or a certain subtree) using ScrollbarTheme:

    return MaterialApp(
    ...
      theme: ThemeData(
        ...
        scrollbarTheme: ScrollbarThemeData(
          thumbVisibility: MaterialStateProperty.all<bool>(true),
        )
      )
    )

It's good to prefer themes for styling like this, so avoid doing more than once.

You'll still need to add a Scrollbar and Controller as described in other answers though.

Equiponderate answered 4/3, 2022 at 20:45 Comment(2)
I don't have a Scrollbar Controller yet your code works for meGrison
ScrollbarTheme method works. Thankyou!Maudiemaudlin
A
6

Use draggable_scrollbar package. It provides a dragable scrollbar with option to make the scrollbar always visible. For example, you can use the following code

 DraggableScrollbar.arrows(
  alwaysVisibleScrollThumb: true, //use this to make scroll thumb always visible
  labelTextBuilder: (double offset) => Text("${offset ~/ 100}"),
  controller: myScrollController,
  child: ListView.builder(
    controller: myScrollController,
    itemCount: 1000,
    itemExtent: 100.0,
    itemBuilder: (context, index) {
      return Container(
        padding: EdgeInsets.all(8.0),
        child: Material(
          elevation: 4.0,
          borderRadius: BorderRadius.circular(4.0),
          color: Colors.purple[index % 9 * 100],
          child: Center(
            child: Text(index.toString()),
          ),
        ),
      );
    },
  ),
);
Atwood answered 30/12, 2019 at 11:18 Comment(3)
do you have any solution for not use plug in? why they didn't add 1 parameter like isScrollbarAlwaysVisible.Outdistance
There are open issues and pull requests regarding this on the flutter repo, but they don't have the, implementation yet. If you don't wanna use plugin, check out this gits, this creates a custom scrollview widget with always visible scroll bar as well allows to customize the scrollbar gist.github.com/slightfoot/beb74749bf2e743a6da294b37a7dcf8dAtwood
isScrollbarAlwaysVisible does not exist in the new versions of flutterElyn
S
3

'isAlwaysShown' is deprecated and shouldn't be used. Use thumbVisibility instead.

Example:

Scrollbar(
   controller: ScrollController(),
    thumbVisibility: true,
      child: SingleChildScrollView(
        child: Column(
Seigneur answered 5/10, 2022 at 8:56 Comment(0)
B
1

thumbVisibility make true for show always scroll bar for list in scrollbar widget

Scrollbar(thumbVisibility: true,)
Brennabrennan answered 4/8, 2022 at 19:3 Comment(0)
S
0

you can add to SingleChildScrollView or ListView.

physics: const AlwaysScrollableScrollPhysics(),
Schrick answered 21/4, 2023 at 13:27 Comment(0)
F
0

'isAlwaysShown' is deprecated.

'thumbVisiblity' with MaterialStateProperty is deprecated.

You'll need to use thumbVisibility with WidgetStateProperty

Example:

 return MaterialApp(
     ...
     theme: ThemeData(
         ...
         scrollbarTheme: ScrollbarThemeData(
             thumbVisibility: WidgetStateProperty.all<bool>(true),
         )
     )
 );
Feast answered 15/7, 2024 at 9:21 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.