How to remove scroll glow?
DartFlutterDart Problem Overview
By default, flutter adds a glowing effect on ListView
/GridView
/... to overscrolls on android phones
I would like to remove this effect entirely or on one specific scrollable.
I know that I can change ScrollPhysics
to change between Bounce/Clamp. But this doesn't actually remove the glow effect.
What can I do ?
Dart Solutions
Solution 1 - Dart
The glow effect comes from GlowingOverscrollIndicator
added by ScrollBehavior
To remove this effect, you need to specify a custom ScrollBehavior
. For that, simply wrap any given part of your application into a ScrollConfiguration
with the desired ScrollBehavior
.
The following ScrollBehavior
will remove the glow effect entirely :
class MyBehavior extends ScrollBehavior {
@override
Widget buildOverscrollIndicator(
BuildContext context, Widget child, ScrollableDetails details) {
return child;
}
}
To remove the glow on the whole application, you can add it right under MaterialApp
:
MaterialApp(
builder: (context, child) {
return ScrollConfiguration(
behavior: MyBehavior(),
child: child,
);
},
home: new MyHomePage(),
);
To remove it on a specific ListView
, instead wrap only the desired ListView
:
ScrollConfiguration(
behavior: MyBehavior(),
child: ListView(
...
),
)
This is also valid if you want to change the effect. Like adding a fade when reaching borders of the scroll view.
Solution 2 - Dart
The glow will disappear by changing the ListView's physics
property to BouncingScrollPhysics
to imitate the List behavior on iOS.
ListView.builder(
physics: BouncingScrollPhysics(),
}
Solution 3 - Dart
The above solution did not work for me. I did this from another solution.
Wrap it with this widget to remove the shadow completely:
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (overscroll) {
overscroll.disallowGlow();
},
child: new ListView.builder(
//Your stuff here.
),
),
Solution 4 - Dart
try this work for me mybe work for you to
ScrollConfiguration(
behavior: new ScrollBehavior()..buildViewportChrome(context, null, AxisDirection.down),
child: SingleChildScrollView()
);
Solution 5 - Dart
You can wrap your SingleChildScrollView or ListView.
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
return;
},
child: SingleChildScrollView()
)
Solution 6 - Dart
You can try BouncingScrollPhysics with all list or grid or scrollview:
//ScrollView:
SingleChildScrollView(
physics: BouncingScrollPhysics(),
)
//For ListView:
ListView.builder(
physics: BouncingScrollPhysics(),
}
//GridView
GridView.Builder(
physics: BouncingScrollPhysics(),
)
Solution 7 - Dart
You don't need to build your own custom ScrollBehavior class. Instead, just wrap your scrollable widget in a ScrollConfiguration widget and set the behavior property to:
const ScrollBehavior().copyWith(overscroll: false)
.
Full code example:
ScrollConfiguration(
behavior: const ScrollBehavior().copyWith(overscroll: false),
child: PageView(
physics: const PageScrollPhysics(),
controller: model.pageController,
children: [
PageOne(),
PageTwo(),
PageThree(),
PageFour(),
],
),
),
Solution 8 - Dart
Update on 2021
as buildViewportChrome is deprecated on March `21, we may have new way to implement this
A. Working Solution
class MyCustomScrollBehavior extends MaterialScrollBehavior {
@override
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
return child;
}
}
class MainApp extends StatelessWidget {
const MainApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
title: 'App Title',
home: HomeUI(),
);
}
}
B. Explanation
By default, Flutter wraps any child widget into GlowingOverscrollIndicator as below code.
@override
Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) {
switch (getPlatform(context)) {
case TargetPlatform.iOS:
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
return child;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
return GlowingOverscrollIndicator(
axisDirection: details.direction,
color: Theme.of(context).colorScheme.secondary,
child: child, // < ---------- our Child Widget is wrapped by Glowing Indicator
);
}
}
So we can easily override it, by directly return child without wrapping it to GlowingOverscrollIndicator
class MyCustomScrollBehavior extends MaterialScrollBehavior {
@override
Widget buildOverscrollIndicator(
BuildContext context, Widget child, ScrollableDetails details) {
return child;
}
}
Solution 9 - Dart
You can also try
SingleChildScrollView(
physics: ClampingScrollPhysics(),
)
Solution 10 - Dart
If you migrated to null safety, you might get issues with the behavior. You can use this method that works with null safety:
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification? overscroll) {
overscroll!.disallowGlow();
return true;
},
child: child,
),
Solution 11 - Dart
I have used below one for Scroll body without Scroll glow effect
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ScrollConfiguration(
behavior: new ScrollBehavior()
..buildViewportChrome(context, null, AxisDirection.down),
child: SingleChildScrollView(
Solution 12 - Dart
Adding "physics: BouncingScrollPhysics()" to the listview.builder solves this problem.
Solution 13 - Dart
The currently accepted answer is outdated in the current version of Flutter.
Scroll behavior's ScrollBehavior.copyWith()
method has an overscroll
flag which can be set to false to avoid having to create your own ScrollBehavior class.
For example:
ScrollConfiguration(
behavior: MaterialScrollBehavior().copyWith(overscroll: false),
child : someScrollableWidget
)
`
It isn't good practice to just change the scroll behavior, as you may lose the native scrolling feel when running your app on different devices.
Solution 14 - Dart
Please add physcis as PageScrollPhysics
SingleChildScrollView(
...
physics: PageScrollPhysics(),
...
Solution 15 - Dart
After Flutter 2.10
update Previous NotificationListener parameter code has been removed/deprecated.
New Code
NotificationListener<OverscrollIndicatorNotification>(
onNotification: ((overscroll) {
overscroll.disallowIndicator(); //previous code overscroll.disallowGlow();
return true;
}),
child: ListView(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 15),
scrollDirection: Axis.horizontal,
children: List.generate(
items.length,
(index) => Padding(
padding: const EdgeInsets.only(right: 15),
child: AspectRatio(
aspectRatio: 13 / 9,
child:
LayoutBuilder(builder: (context, boxcon) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: const [
BoxShadow(
color: Colors.black12,
spreadRadius: 5,
blurRadius: 12)
],
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(items[index])),
color: greengradientcolor,
),
);
}),
))),
),
),