Mastering Scroll Event Tracking in Flutter: A Practical Guide


Scrolling is a ubiquitous interaction in mobile apps, and being able to track scroll events accurately can lead to better user experiences and informed design decisions. In this blog post, we’re diving into the world of efficient scroll event tracking in Flutter. Even if you’re not a Flutter wizard, worry not — I’ve got you covered with a step-by-step breakdown of the code and concepts.
Getting Started
To start, let’s take a look at the core components of the code we’ll be discussing. The main parts consist of main.dart
and a handy mixin named tracking_scroll.dart
.
main.dart
import 'package:flutter/material.dart';
import 'package:scroll_example/tracking_scroll.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: ScrollExample(),
);
}
}
class ScrollExample extends StatefulWidget {
const ScrollExample({super.key});
@override
State<ScrollExample> createState() => _ScrollExampleState();
}
class _ScrollExampleState extends State<ScrollExample> with TrackingScroll {
late ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
initiateTracking(
_scrollController,
Axis.vertical,
(percent, typeOfScroll) {
debugPrint('Scrolling $typeOfScroll at $percent%');
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: const Text('Scroll Tracking'),
),
body: ListView.builder(
itemCount: 100,
controller: _scrollController,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
);
}
}
Here’s a quick rundown:
We have the
ScrollExample
widget, which is our playground for scroll event tracking.Inside the
_ScrollExampleState
state class, we're embracing the power of theTrackingSrcoll
mixin to efficiently track scroll events.initState()
sets up the necessary components for scroll tracking, including a scroll controller, scroll direction, and the callback function.
scroll_tracker.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
typedef ScrollTrackerCallback = void Function(
int scrollPercent, String typeOfScroll);
mixin TrackingScroll {
ScrollController? _scrollController;
Axis? _scrollDirection;
ScrollTrackerCallback? _onScrolled;
void initiateTracking(
ScrollController scrollController,
Axis scrollDirection,
ScrollTrackerCallback? onScrolled,
) {
_scrollController = scrollController;
_scrollDirection = scrollDirection;
_onScrolled = onScrolled;
_scrollController?.position.isScrollingNotifier
.addListener(_scrollChangeListener);
}
void _scrollChangeListener() {
if (_scrollController == null) return;
final scrollController = _scrollController!;
if (!scrollController.position.isScrollingNotifier.value) {
final percent = scrollController.position.pixels *
100 ~/
scrollController.position.maxScrollExtent;
var typeOfScroll = '';
if (_scrollDirection == Axis.horizontal) {
if (scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
typeOfScroll = 'sroll left';
} else if (scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
typeOfScroll = 'sroll right';
}
} else {
if (scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
typeOfScroll = 'sroll up';
} else if (scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
typeOfScroll = 'sroll down';
}
}
_onScrolled?.call(percent, typeOfScroll);
}
}
}
In this snippet:
We have a cool
ScrollTrackerCallback
type that we'll use for our scroll event callback.And here’s where the magic happens — the
TrackingSroll
mixin encapsulates the scroll tracking logic we're about to explore.
The Scroll Tracking Magic
Let’s pull back the curtains and reveal how this scroll tracking magic works under the hood.
Inside the
TrackingSroll
mixin, there are a few hidden gems:_scrollController
,_scrollDirection
, and_onScrolled
. These store our scroll controller, scroll direction, and the callback function, respectively.The
initiateTracking
method initiates the scroll tracking process. It takes in aScrollController
, anAxis
(to define scroll direction), and a callback function. This callback function is your secret weapon to be triggered whenever a scroll event is detected.Here comes the star of the show —
_scrollChangeListener
. It gets attached as a listener to the scroll controller'sisScrollingNotifier
. This function is called every time there's a scroll event.When the
_scrollChangeListener
detects that scrolling has stopped (yep, only when it stops), it calculates the scroll percentage based on the current scroll position.Depending on whether you’re scrolling vertically or horizontally, it figures out if you’ve been scrolling up, down, left, or right.
Armed with the scroll percentage and direction, the callback function you provided gets its moment to shine.
The Grand Finale
Tracking scroll events efficiently in Flutter is like having a crystal ball into your users’ interaction with your app. By tapping into the power of the TrackingScroll
mixin, you can bring your app to life with engaging and responsive scrolling behaviors.
Remember, the ScrollTrackerCallback
is your canvas – you can customize it to suit your app's unique needs. Whether you're building a simple list or a complex UI with intricate scrolling behaviors, this approach has got your back.
And here’s a neat little secret: You’re not limited to either StatelessWidget
or StatefulWidget
– this mixin can be your trusty sidekick in both realms.
So, there you have it! A deep dive into scroll event tracking in Flutter that’s designed to empower developers of all levels. Go ahead, experiment, and take your Flutter app’s scrolling to the next level.
Subscribe to my newsletter
Read articles from NonStop io Technologies directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

NonStop io Technologies
NonStop io Technologies
Product Development as an Expertise Since 2015 Founded in August 2015, we are a USA-based Bespoke Engineering Studio providing Product Development as an Expertise. With 80+ satisfied clients worldwide, we serve startups and enterprises across San Francisco, Seattle, New York, London, Pune, Bangalore, Tokyo and other prominent technology hubs.