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 horizontal ListView
which shows promo banners. I wanted to show scrollbar for vertical scrolling, but not for horizontal. I've wrapped the SingleChildScrollView
which makes Column
scrollable in ScrollBar
, 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
There are always multiple ways of scrolling with an input device. Laptops have touchpads, phones have touchscreens, mouses have scroll wheels. On top of that, you can modify your scroll direction for a scroll wheel by holding shift.
To enable horizontal scrolling, we can use the CSS property overflow-x. If we assign the value scroll to the overflow-x property of the container element, the browser will hide horizontally overflowing content and make it accessible via horizontal scrolling.
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With