In Flutter, a NotificationListener is a widget that allows you to listen to and respond to notifications dispatched by descendant widgets in the widget tree.
It acts as a middleman between the widgets that dispatch notifications (senders) and the widgets that want to receive and handle those notifications (listeners).
The NotificationListener widget wraps its child widget and provides callbacks for various types of notifications. When a descendant widget in the widget tree dispatches a notification, the NotificationListener intercepts it and invokes the corresponding callback.
The primary purpose of a NotificationListener is to enable communication between different parts of the widget tree without tight coupling. It promotes a decoupled architecture by allowing widgets to send notifications without needing direct references to the listening widgets.
Here’s an example to illustrate its usage:
NotificationListener<ScrollNotification>(
onNotification: (notification) {
// Handle scroll notifications here
if (notification is ScrollStartNotification) {
// Do something on scroll start
} else if (notification is ScrollUpdateNotification) {
// Do something on scroll update
} else if (notification is ScrollEndNotification) {
// Do something on scroll end
}
// Return true to stop propagation, or false to continue
return false;
},
child: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
);
In the above example, the NotificationListener listens to ScrollNotification dispatched by the ListView widget. It provides an onNotification callback, which receives the notification object. Depending on the type of notification, you can perform specific actions or handle events accordingly. By returning true from the callback, you can stop the propagation of the notification to other listeners.
based on above example we have shared screen shot of another NotificationListener example :-
import 'package:flutter/material.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Test Notification Listener',),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key ?key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
List<Widget> list = [];
for (int i = 0; i < 100; i++) list.add(buildContainer());
return Scaffold(
body: ListView(children: list));
}
Widget buildContainer() {
ScrollController _scrollController = ScrollController();
return NotificationListener<ScrollNotification>(
onNotification: (scrollState) {
if (scrollState is ScrollEndNotification && scrollState.metrics.pixels != 160) {
Future.delayed(const Duration(milliseconds: 100), () {}).then((s) {
_scrollController.animateTo(160,
duration: Duration(milliseconds: 500), curve: Curves.ease);
});
}
return false;
},
child: Container(
height: 160,
margin: EdgeInsets.only(bottom: 1),
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
controller: _scrollController,
children: <Widget>[
Container(
width: 360,
height: 20,
color: Colors.red,
),
Container(
width: 160,
height: 20,
color: Colors.blue,
),
],
),
),
);
}
}
package for notificationListener
You can also use package of notificationListener
https://pub.dev/packages/flutter_notification_listener
The NotificationListener widget is particularly useful in scenarios where you need to observe and react to events such as scrolling, focus changes, text input, and more. It promotes flexibility, reusability, and separation of concerns in your Flutter app’s architecture.