1. The introduction
One of the most interesting things about ScrollView’s source code is that it has been researched. This is the introduction to the NotificationListener component. This is part of the ScrollView#build source code. You can see that when keyboardDismissBehavior is onDrag, a NotificationListener component is nested on top of the built component, And is processed logically in the onNotification.
The enumeration of ScrollViewKeyboardDismissBehavior are only two elements.
enum ScrollViewKeyboardDismissBehavior {
manual,
onDrag,
}
Copy the code
The ListView inherits from the ScrollView, and the keyboardDismissBehavior parameter in the constructor initializes this member as defined in the ScrollView. The core code for the test is as follows:
Manual and onDrag have the following effects: When the current keyboard is displayed as manual, the keyboard is not actively hidden during the list slide. With onDrag, the keyboard actively hides the list when you swipe it.
manual | onDrag |
---|---|
The value of NotificationListener is clearly recognized by a small detail in the source code. It can listen to the process of sliding and call back relevant data for logical processing by the user.
2. Know NotificationListener
NotificationListener is a StatelessWidget that accepts a generic Notification family. The constructor must pass in a child component that can set the listener for onNotification.
OnNotification member’s type is NotificationListenerCallback < T >, you can see it is a function type, return a bool value. The input argument must be a generic T object and must be a Subclass of Notification. That is, the function calls back a data and returns an identity to control some logic.
-- -- -- - > [NotificationListener# onNotification statement] -final NotificationListenerCallback<T>? onNotification;
typedef NotificationListenerCallback<T extends Notification> =
bool Function(T notification);
Copy the code
As a StatelessWidget, the most important is the build method. But as you can see from the source code, the component directly returns the child passed in by the consumer, that is, it does not care about the component’s build logic.
Finally, the class also has a private method, _Dispatch, in which the Notification object needs to be passed in. As you can see, this is the onNotification method triggered by the consumer.
3. Know the Notification
There are so many notificationListeners that it is difficult to get a complete understanding of NotificationListener without knowing this class. Notification is an abstract class; it does not inherit from any class. There are two common methods: visitAncestor and Dispatch.
Since Notification is an abstract class, objects cannot be constructed directly, so the Flutter framework naturally provides relevant implementation classes. Here are a number of implementation classes for Notification, including ScrollUpdateNotification in the introduction. So we know which notifications we can listen to.
4. Recognize the use of NotificationListener
For example, let’s listen for ScrollUpdateNotification via NotificationListener, so that the _onNotification callback can call back the notification gliding data when it slides. We can use this object for logical processing.
class ListViewDemo extends StatelessWidget {
const ListViewDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return NotificationListener<ScrollUpdateNotification>(
onNotification: _onNotification,
child: ListView(
children: List.generate(
60,
(index) => ItemBox(index: index, )).toList()),
);
}
bool _onNotification(ScrollUpdateNotification notification) {
print('====dragDetails:${notification.dragDetails}'
'====pixels:${notification.metrics.pixels}');
return false; }}Copy the code
Test item units are shown below, using the ItemBox component.
class ItemBox extends StatelessWidget {
final int index;
const ItemBox({Key? key, required this.index}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1 / window.devicePixelRatio,
))),
height: 56,
child: Text(
'the first$indexA ',
style: TextStyle(fontSize: 20),),); }}Copy the code
We can listen for any Notification type, such as the OverscrollNotification below. This listener will be triggered when the list slides to the top or bottom, and we can get the overscroll size in the callback data.
class ListViewDemo extends StatelessWidget {
const ListViewDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return NotificationListener<OverscrollNotification>(
onNotification: _onNotification,
child: ListView(
children: List.generate(
60,
(index) => ItemBox( index: index,)).toList()),
);
}
bool _onNotification(OverscrollNotification notification) {
print('====dragDetails:${notification.dragDetails}'
'====pixels:${notification.metrics.pixels}'
'=====overscroll:${notification.overscroll}');
return false; }}Copy the code
In addition to listening on a single Notification, we can also listen on multiple Notifications via the parent level. Here is the code for listening on the top-level abstract Notification class. A simple swipe up the log shows that multiple types of Notification notifications can be heard at the same time, and we can distinguish them by type.
class ListViewDemo extends StatelessWidget {
const ListViewDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return NotificationListener<Notification>(
onNotification: _onNotification,
child: ListView(
children: List.generate(
60,
(index) => ItemBox( index: index,)).toList()),
);
}
bool _onNotification(Notification notification) {
print('====Notification type:${notification.runtimeType}= = = = = = ');
return false; }}Copy the code
5 source code for NotificationListener use
The most classic is the use of NotificationListener in the Scrollbar source code, which listens for the five kinds of ScrollNotification notifications and is processed by the _handleScrollNotification.
By nesting a Scrollbar around the ListView, the indicator appears on the right during the slide.
Scrollbar(
child: ListView(
children: List.generate(
60,
(index) => ItemBox(index: index,)).toList()),
),
Copy the code
ScrollNotification RefreshIndicator internal components is also based on the monitoring and OverscrollIndicatorNotification notification.
6. NotificationListener Function of the returned value in the listener
As you can see from the source code, when false is returned, the notification can continue to be distributed to the upper node. The reverse means that the advice is truncated.
For example, put a NotificationListener below the Scrollbar and return true when listening. In this way, when the ListView’s sliding event is distributed up to the NotificationListener, it is intercepted and cannot be sent up to the listener in the Scrollbar. Which means the Scrollbar doesn’t work.
The slide system of Flutter allows us to listen for slides of components anywhere through Notification distribution and listening. Thus the sliding events are greatly decoupled. As for the specific process of sliding notification, it is not a word can be introduced. As an ordinary user, it is enough to know this. My fourth volume, Exploration of The Flutter sliding system, will provide a comprehensive analysis of the source code implementation of the Flutter sliding system.