How do I enable scrollbar for vertical scroll and disable for horizontal?
Solution 1
class NoScrollbar extends StatelessWidget {
final Widget child;
const NoScrollbar({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollNotification>(
onNotification: (_) => true,
child: child,
);
}
}
Just wrap the NoScrollbar Widget around the Scrolling Widget, you don't want to have the Scrollbar appear. This solved it for me!
Solution 2
Niklas answer did not work for me in Flutter 2.5. I don't know if it's because my layout is different or what. But if you have a PageView (as a carousel for example) inside a ListView the way I found to remove PageView's scrollbar is the following.
Add to Scrollbar
widget a notificationPredicate
:
notificationPredicate: (ScrollNotification notification) {
return notification.depth == 0 && notification.metrics.axis == Axis.vertical;
}
This will only show scrollbar for vertical interactions.
Flutter documentation about notificationPredicate.
Tumist
Updated on December 18, 2022Comments
-
Tumist over 1 year
I've been building layout with both horizontal and vertical scrolling. Vertical scrollable
Column
is for main content and is populated by different views, including horizontalListView
which shows promo banners. I wanted to show scrollbar for vertical scrolling, but not for horizontal. I've wrapped theSingleChildScrollView
which makesColumn
scrollable inScrollBar
, but the bar appeared on both vertical on horizontal scrolls. Is there any fine-tuning for these kinds of things?Sample to demonstrate the issure
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Scrollables', home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Scrollbar( child: new SingleChildScrollView( child: new Container( padding: EdgeInsets.only(top: 40.0), child: Column(children: <Widget>[ HorizontalListView(), VerticalListView(), ]), )), ), ); } } class HorizontalListView extends StatelessWidget { var items = new List<String>(); _addNewItem(int index) { items.add("Item $index"); } @override Widget build(BuildContext context) => Container( height: 120, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: 15, itemBuilder: (context, index) { return Card(child: ListItem(index)); })); } class VerticalListView extends StatelessWidget { var items = new List<String>(); _addNewItem(int index) { items.add("Item $index"); } @override Widget build(BuildContext context) => Container( child: ListView.builder( scrollDirection: Axis.vertical, itemCount: 50, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { return ListItem(index); })); } class ListItem extends StatelessWidget { int _index; ListItem(this._index); @override Widget build(BuildContext context) { return Container( width: 280, child: Text("Item ${this._index}"), ); } }
Pay attention to the bottom on horizontal scrolling
-
MobileMon over 3 yearsI don't understand how this works but it does work
-
nt4f04und over 3 years@MobileMon flutter scrollbar is based on
ScrollNotification
s, and because returningtrue
from theNotificationListener<ScrollNotification>
onNotification
will prevent notication bubbling, it won't reach theScrollbar
widget and it thus it won't appear