Question: There are two options to retrieve the scroll position for a CustomScrollView. The [documentation](https://docs.flutter.io/flutter/widgets/CustomScrollView-class.html) states the following: 

> 
> ScrollNotification and NotificationListener, which can be used to watch the scroll position without using a ScrollController.
> 
> 
> 

So we have the following options:

1. NotificationListener with ScrollNotification
2. ScrollController

In which situation do you useNotificationListener with ScrollNotification vs ScrollController?

Thank you :)

Answer: 
Although you can use both ScrollNotification and ScrollController to listen scroll position changes, and many times it is not going to be difference, you should keep in mind some details in order to better choose the best tool for the job:

**ScrollController**

* To use a ScrollController you should use a Stateful widget, so that it can be properly dispose.
* Even if you can use the same ScrollController to control several scrollable widgets, some operations, such as reading the scroll offset, require the controller to be used with a single scrollable widget.
* If you want to change the scroll position, you are going to need a ScrollController (jumpTo / animateTo).
* When you listen to a ScrollController, you are listening to [ScrollPosition](https://api.flutter.dev/flutter/widgets/ScrollPosition-class.html) changes, what is not exactly the same as [ScrollNotification](https://api.flutter.dev/flutter/widgets/ScrollNotification-class.html). Using ScrollNotifications you can differentiate among several types of events related to the scrolling action, like scroll start, scroll end, dirección change, etc.

**NotificationListener**

* NotificationListener is just another widget, so yo don't need to create a Stateful widget.
* It listens ScrollNotifications from all scrollable widgets below in the widget tree, as notifications propagate upwards. So it is not constraint to listen only one widget.
* You cannot change the scroll position from a NotificationListener. It is read only.
* You listen to ScrollNotification, and not to changes in a ScrollPosition, so you can recognize easily which king of event has just happened.
it my demo use NotificationListener with ScrollController. After drag a litter left, the blue part will automatic move

```
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, 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,
            ),
          ],
        ),
      ),
    );
  }
}

```