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: 
If you're using `NestedScrollView` with nested scrollers, using a scrollController on the inner scrollers will break the link with `NestedScrollView` meaning `NestedScrollView` will no longer control the complete scrolling experience. To get information about the scroll positions of the inner scrollers in this case you would use a `NotificationListener` with `ScrollNotification`.

```
NotificationListener<ScrollNotification>(
  child: ListView.builder(
    itemCount: 10
    itemBuilder: (BuildContext context, int index) {
      return Text('Item $index');
    },
  ),
  onNotification: (ScrollNotification scrollInfo) {
    if (scrollInfo.metrics.pixels ==
        scrollInfo.metrics.maxScrollExtent) {
      onLoadMore();
    }
  },
);

```

Related Answer [here](https://stackoverflow.com/a/46853315/2190496).
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,
            ),
          ],
        ),
      ),
    );
  }
}

```