Remove the top padding from ScrollBar when wrapping ListView
Asked Answered
A

2

7

I am trying to add ScrollBar to ListView in Flutter but the ScrollBar still have padding on top when scrolling to the start of the ListView.

I included a snapshot of the application so you can understand the problem better. it`s in the indicator of the scrollbar widget the top padding should not be there ,so the start of the scrollbar indicator should touch the bottom edge of the blue DrawerHeader.

here is my code:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final sc = ScrollController(initialScrollOffset: 0);

    final res = MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Driver App'),
        ),
        body: null,
        drawer: Drawer(
          child: Container(
            padding: EdgeInsets.zero,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                DrawerHeader(
                  child: Text('Drawer Header'),
                  decoration: BoxDecoration(
                    color: Colors.blue,
                  ),
                  margin: EdgeInsets.zero,
                ),
                Expanded(
                  child: Scrollbar(
                    radius: Radius.circular(30),
                    thickness: 10,
                    controller: sc,
                    isAlwaysShown: true,
                    child: ListView(
                      shrinkWrap: false,
                      controller: sc,
                      padding: EdgeInsets.only(top: 0),
                      children: <Widget>[
                        ListTile(
                          title: Text('Item 2'),
                          onTap: () {
                            // Update the state of the app.
                            // ...
                          },
                        ),
                        ListTile(
                          title: Text('Item 2'),
                          onTap: () {
                            // Update the state of the app.
                            // ...
                          },
                        ),
                        ListTile(
                          title: Text('Item 2'),
                          onTap: () {
                            // Update the state of the app.
                            // ...
                          },
                        ),
                        ListTile(
                          title: Text('Item 2'),
                          onTap: () {
                          },
                        ),
                        ...
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ), // Populate the Drawer in the next step.
        ),
      ),
    );

    return res;
  }
}

result when scrolling position is 0:

enter image description here

Anetta answered 17/10, 2020 at 16:42 Comment(0)
T
24

enter image description here use MediaQuery.removePadding widget with removeTop: true

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final sc = ScrollController(initialScrollOffset: 0);

    final res = MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Driver App'),
        ),
        body: null,
        drawer: Drawer(
          child: Container(
            padding: EdgeInsets.zero,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                DrawerHeader(
                  child: Text('Drawer Header'),
                  decoration: BoxDecoration(
                    color: Colors.blue,
                  ),
                  margin: EdgeInsets.zero,
                ),
                Expanded(
                  child: MediaQuery.removePadding(
                    context: context,
                    removeTop: true,
                    child: Scrollbar(
                      radius: Radius.circular(30),
                      thickness: 10,
                      controller: sc,
                      isAlwaysShown: true,
                      child: ListView(
                        shrinkWrap: false,
                        controller: sc,
                        padding: EdgeInsets.only(top: 0),
                        children: <Widget>[
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                              // Update the state of the app.
                              // ...
                            },
                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                              // Update the state of the app.
                              // ...
                            },
                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                              // Update the state of the app.
                              // ...
                            },
                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                            },

                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                            },

                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                            },

                          ),
                          ListTile(
                            title: Text('Item 2'),
                            onTap: () {
                            },

                          )
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ), // Populate the Drawer in the next step.
        ),
      ),
    );

    return res;
  }
}
Tacit answered 17/10, 2020 at 17:52 Comment(2)
BTW I got an error when I tried to run your solution the context should be coming from MaterialApp Widget So I moved the home part to other widget to fix this error.Anetta
Thanks! The questions is why does it has padding in the first place? Not for all ListViews this padding appear by default. Very weird..Gronseth
M
0

Scrollbar padding is set as follows:

  ScrollbarPainter _buildMaterialScrollbarPainter() {
        return ScrollbarPainter(
          color: _themeColor,
          textDirection: _textDirection,
          thickness: widget.thickness ?? _kScrollbarThickness,
          radius: widget.radius,
          fadeoutOpacityAnimation: _fadeoutOpacityAnimation,
          padding: MediaQuery.of(context).padding,
        );
      }

The solution to remove the padding in your case would be to place your Scaffold inside the SafeArea.

  home: SafeArea(
    child: Scaffold(
      appBar: AppBar(
        title: Text('Driver App'),
      ),
Mattie answered 17/10, 2020 at 17:49 Comment(7)
thank you, Wrapping Scaffold with a SafeArea did the trick, but I find @karzan-kamal Solution more convenient.Anetta
Yes, his answer was correct, I hadn't seen MediaQuery.removePadding yet, it seemed very useful.Mattie
SafeArea did not work for me but MediaQuery.removePadding worked. return MediaQuery.removePadding( context: context, removeTop: true, child: ListView.builder(........Precipitous
where do i place the _BuldMaterialScrollBarPainter method?Gravedigger
@Gravedigger Nowhere, _buildMaterialScrollbarPainter is a function of the flutter's internal api, it's the way it set the Scrollbar padding, just put your Scaffold inside of a SafeArea or use MediaQuery.removePadding() widget.Mattie
but what if instead of removing the padding someone wanted to change the padding valuesGravedigger
@Gravedigger i think you could wrap the scroll bar with MediaQuery.removePadding() and put it inside a padding widget, that way u could define what padding it will be.Mattie

© 2022 - 2024 — McMap. All rights reserved.