다음과 같은 Scrollbar이 있는 ListView를 구현할 때, ListView의 시작과 끝부분에서 드래그를 했을시 다음과 같이 UI가 원하지 않게 움직이게 된다.
이를 해결할 방법을 살펴보자.
ListView.builder(
shrinkWrap: true,
physics : ClampingScrollPhysics(),
itemBuilder: (_, index) => ListTile(
title: Text("index: $index"),
),
),
physics 설정을 통해 scroll의 특성을 변경 가능하다.
ClampingScrollPhysics() - Android 기본 설정 값,시작과 끝을 도달 했을때 효과를 보여줌
BouncingScrollPhysics() - IOS의 기본 세팅과 유사, List의 끝에 도달했을 때 bouncing
ListView - physics에 관한 자세한 설명참고
:https://medium.com/flutter-community/flutter-listview-and-scrollphysics-a-detailed-look-7f0912df2754
build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
changePosition(notification);
return true;
},
child: Widget(),
);
}
changePosition(ScrollNotification notification) {
if (isDragInProcess) {
return;
}
setState(() {
if (notification is ScrollUpdateNotification) {
if(notification.metrics.outOfRange){
}else{
}
}
}
);
}
Widget
스크롤 제어하고 싶은 위젯에 NotificationListener 적용
isDragInProcess라는 변수를 통해 사용자가 스크롤중인지 확인
changePosition 함수에 있는 notification의 속성값들을 다음과 같이 있다
다양한 기기의 화면에 맞추기 위해 SingleChildScrollView를 자주 쓰게 된다.
그러면 화면상단이나 하단부분에서 스크롤을 하면 다음과 같은 효과가 나온다.
이러한 효과를 없애고 싶을때 다음과 같이 적용하면 된다.
NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowGlow();
return;
},
child: SingleChildScrollView()
)
화면의 공간보다 더 많이 스크롤 했을때를 감지하여 해당 효과를 없애준다.
아니면 다음과 같이 적용해도 같은 결과를 얻을 수 있다.
child : SingleChildScrollView(
physics : ClampingScrollPhysics()
child: Widget()
)
BouncingScrollPhysics () : 목록의 끝 / 시작시 bouncing 스크롤(GlowEffect,Bouncing 효과)
NeverScrollableScrollPhysics () : 해당 영역에서는 스크롤 불가
ClampingScrollPhysics () : GlowEffect가 제거된 상태로 정상 동작