[Flutter]Singlechildscrollview-glow,physics

Lia·2022년 8월 17일
0

🔵 Flutter

목록 보기
10/12
post-thumbnail

다음과 같은 Scrollbar이 있는 ListView를 구현할 때, ListView의 시작과 끝부분에서 드래그를 했을시 다음과 같이 UI가 원하지 않게 움직이게 된다.

이를 해결할 방법을 살펴보자.

1. ListView의 Physics 설정

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

2. GestureDetector을 통한 스크롤 제어


 Widget 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{
       }
       }
     }
   );
 }

스크롤 제어하고 싶은 위젯에 NotificationListener 적용
isDragInProcess라는 변수를 통해 사용자가 스크롤중인지 확인
changePosition 함수에 있는 notification의 속성값들을 다음과 같이 있다

  • notification.metrics.outOfRange : 스크롤하는 구역이 최상단 / 최하단일 경우(위의 사진과 같이) -> return true / else return false
  • notification.scrollDelta : 스크롤한 위젯이 얼마나 이동을 하는가에 대한 Value 반환(double)
  • notification.metrics.atEdge : 위젯의 위치가 구역의 위 또는 아래에 있는지에 대한 bool값 반환
  • notification.dragDetails : 사용자가 위젯 스크롤 했을때 x축과 y축방향으로 얼마나 했는지 반환 (offset)
    notification.metrics.outOfRange가 false 일때 원하는 움직임을 else{}에를 작성해주면 된다.

🔎GlowEffect제거

다양한 기기의 화면에 맞추기 위해 SingleChildScrollView를 자주 쓰게 된다.
그러면 화면상단이나 하단부분에서 스크롤을 하면 다음과 같은 효과가 나온다.


이러한 효과를 없애고 싶을때 다음과 같이 적용하면 된다.

NotificationListener<OverscrollIndicatorNotification>(
  onNotification: (OverscrollIndicatorNotification overscroll) {
    overscroll.disallowGlow();
    return;
  },
  child: SingleChildScrollView()
)

화면의 공간보다 더 많이 스크롤 했을때를 감지하여 해당 효과를 없애준다.
아니면 다음과 같이 적용해도 같은 결과를 얻을 수 있다.

child : SingleChildScrollView(
physics : ClampingScrollPhysics()
child: Widget()
)

BouncingScrollPhysics () : 목록의 끝 / 시작시 bouncing 스크롤(GlowEffect,Bouncing 효과)
NeverScrollableScrollPhysics () : 해당 영역에서는 스크롤 불가
ClampingScrollPhysics () : GlowEffect가 제거된 상태로 정상 동작

profile
꺾이지않기ᕙ༼*◕_◕*༽ᕤ

0개의 댓글