DEV Community

Pedro Massango
Pedro Massango

Posted on

Scrolling like a Pro - Creating custom scroll behaviors

Hi there, long time no see, today I have decided to share some common tips and tricks on scrolling with Flutter


Why Customize Scroll Behavior in Flutter?

Flutter gives you powerful out of the box scroll widgets like ListView, SingleChildScrollView, and PageView. But sometimes, you need custom scroll effects to:

  • Remove glow on overscroll (Android)
  • Customize scroll physics (bouncy, clamped, paged)
  • Trigger animations or data loads when scrolling
  • Create sticky headers, parallax, or infinite scroll

Let’s see some real code life examples below:

1. Remove Overscroll Glow (Android Ripple)

By default, Android shows a glow effect on overscroll and not every company's design system follow this behavior so there is always a need to get rid of it. To remove it, override the scroll behavior globally:

class NoGlowScrollBehavior extends ScrollBehavior {
  @override
  Widget buildViewportChrome(
    BuildContext context,
    Widget child,
    AxisDirection axisDirection,
  ) {
    return child;
  }
}
Enter fullscreen mode Exit fullscreen mode

Then apply it globally:

MaterialApp(
  scrollBehavior: NoGlowScrollBehavior(),
  home: MyHomePage(),
)
Enter fullscreen mode Exit fullscreen mode

Or locally:

ScrollConfiguration(
  behavior: NoGlowScrollBehavior(),
  child: ListView(...),
)
Enter fullscreen mode Exit fullscreen mode

2. Listen to Scroll Position

Track scroll position or trigger logic on scroll, there are different ways to achieve this and below I will share the implementation using a ScrollController:

final _controller = ScrollController();

@override
void initState() {
  super.initState();
  _controller.addListener(() {
    if (_controller.offset > 100) {
      print('Scrolled past 100 pixels');
    }
  });
}

@override
void dispose() {
  _controller.dispose();
  super.dispose();
}
Enter fullscreen mode Exit fullscreen mode

Usage:

ListView(
  controller: _controller,
  children: [...],
)
Enter fullscreen mode Exit fullscreen mode

3. Custom Scroll Physics (e.g., Bouncing like iOS)

ListView(
  physics: const BouncingScrollPhysics(), // or NeverScrollableScrollPhysics()
  children: [...],
)
Enter fullscreen mode Exit fullscreen mode

You can also combine physics:

physics: const BouncingScrollPhysics(
  parent: AlwaysScrollableScrollPhysics(),
)
Enter fullscreen mode Exit fullscreen mode

4. Scroll to a Widget programmatically

_scrollController.animateTo(
  500.0, // offset
  duration: Duration(milliseconds: 400),
  curve: Curves.easeInOut,
);
Enter fullscreen mode Exit fullscreen mode

Or scroll to a widget using Scrollable.ensureVisible:

Scrollable.ensureVisible(
  context,
  duration: Duration(milliseconds: 300),
  alignment: 0.5,
);
Enter fullscreen mode Exit fullscreen mode

5. Advanced: create a sticky header or a parallax effect

Use CustomScrollView + SliverPersistentHeader:

SliverPersistentHeader(
  pinned: true,
  delegate: MyHeaderDelegate(),
),
Enter fullscreen mode Exit fullscreen mode

Or use packages like:


Summary

Task Tool/Widget
Remove glow ScrollBehavior
Track scroll ScrollController
Customize physics ScrollPhysics
Animate to scroll ScrollController.animateTo()
Sticky/parallax effects CustomScrollView, Sliver widgets

Bonus: infinite scroll example

_controller.addListener(() {
  if (_controller.position.pixels ==
      _controller.position.maxScrollExtent) {
    fetchMoreItems();
  }
});
Enter fullscreen mode Exit fullscreen mode

Flutter gives you the flexibility to tune every aspect of scrolling — whether it's subtle UX improvements or complex scroll-driven required by your company's UX, you're pretty much set to implement everything with Flutter.

Top comments (0)