ListView
나 SingleChildScrollView
와 같이ScrollView
를 상속해 스크롤이 가능한 위젯들을 사용하는 경우, 무한 스크롤 구현 등을 위해 현재 스크롤 위치를 추적할 때가 많다.
일반적인 방법으로는 ScrollController
를 사용해 아래와 같이,
var scrollController = ScrollController();
scrollController.addListener(() {
print(scrollController.position);
});
ScrollController.addListener
를 통해 스크롤 이벤트를 등록하고 위치를 추적할 수 있다.
하지만 NestedScrollView
와 같이 PrimiaryScrollController를 사용하고 있어 직접 생성한 ScrollController
를 사용하기 어려운 경우, 위의 방법을 사용할 수 없기 때문에 다른 방법으로 이벤트를 구현해야한다.
이 때 사용할 수 있는 것이 NotificationListener
다. ScrollView
위젯을 NotificationListener
로 감싸면 스크롤 이벤트를 받을 수 있다.
return NotificationListener(
child: ListView(
children: [Text('A'), Text('B'), Text('C')],
),
onNotification: (scrollNotification) {
//스크롤 시 이 부분에서 이벤트가 발생한다.
return false;
},
onNotification
은 ScrollNotification
을 인자로 넘겨주며, 이 인자를 사용해 현재 위치 등을 구할 수 있다.
bool _onScrollNotification(ScrollNotification scrollNotification) {
var metrics = scrollNotification.metrics;
//세로 스크롤인 경우에만 추적
if (metrics.axisDirection != AxisDirection.down) return false;
if (metrics.extentAfter <= 0) {
//스크롤 끝에 닿은 경우 실행
}
return false;
}
다만 하위 트리에 있는 모든 ScrollView
의 이벤트를 받기 때문에 만약 여러 스크롤 가능한 위젯을 중첩하여 사용하는 경우, metrics.axisDirection
등을 사용하여 방향을 체크하고 사용할 필요가 있다.