flutter FAB Hide/Show

Sunny·2022년 5월 20일

##FAB Hide/Show

정리해야할 것은 참 많은데, 어쩌다보니 FAB Hide/Show를 정리하게 되었다.

FAB = FloatingActionButton => appBar / body / bottomNavigationBar처럼 Scaffold의 아이(?)

앱을 하나 만들면서, FAB를 Hide 시키기 위해서 어떻게 할 지 공식문서를 쥐잡듯이 보다보니.. 1가지 정답을 찾았다. (물론 정답은 많다!)

Visibility를 이용하기

Visibility로 FAB를 감싸고 visible 속성을 이용하는 것이다! (true면 show / false면 hide)

//fluter
Visibility(
visible: true // _visibleButton로 선언하기 (변수명은 자기 맘대로 !)

child: FloatingActionButton(
child:Icon(Icons.home),
onPressed:(){},
),
),

위처럼 사용하면 될 것이다.

그렇다면 visible 속성을 어떻게 이용할 수 있을까??

visible 속성에 변수를 설정해서 초기값을 class에 지정 후에, scroll이 가만히 있다면.. true / 아니라면 false를 주면 될 것이다.

ScrollDirection 이용하기

listview의 controller: _scrollController로 선언 후에 따로 void 함수를 만들어서 _scrollController.addListener를 이용해보자.

ListView 위젯에 controller: _scrollController를 선언해줘야 한다. 그래야 스크롤 컨트롤러를 사용할 수 있다.

late ScrollController _scrollController;를 class에 선언하고
initState 상태 일 때 _scrollController = ScrollController();를 선언한다.

그리고 움직이는 상황에 반응하게 끔 moveScroll이라는 메소드를 생성한다 그리고 initState에 추가해주자.

  
  void initState() {
    super.initState();
    _scrollController = ScrollController();

    moveScroll();
  }
  
  void moveScroll(){
  // ...
  }

그리고 moveScroll에 _scrollController.addListener를 이용하여, 우리가 원하던 스크롤에 따라 hide/show를 반응하게 해야한다.
(but.. 여기선 내가 원하는 것을 할 수 없었다.)

// ScrollDirection을 이용하면 스크롤이 위로 가는 지, 아래로 가는 지, 
// 가만히 있는 지 확인을 할 수 있다. 물론 컨트롤러에서는 position.userScrollDirection에 들어간다.
// 참고로 ScrollDirection.idle은 가만히(?) 있을 때라고 생각중이다.
  void moveScroll() async {
    _scrollController.addListener(() {
      if (_scrollController.position.userScrollDirection ==
          ScrollDirection.forward) {
          // forward는 위로 올라갈 때
        showFloatButton();
      } else if (_scrollController.position.userScrollDirection ==
          ScrollDirection.reverse) {
          // 아래로 올라갈 때
        hideFloatButton();
      }
    });
  }
  void hideFloatButton() {
    setState(() {
      _visibleButton = false;
    });
  }

  void showFloatButton() {
    setState(() {
      _visibleButton = true;
    });
  }

위를 이용하면 스크롤을 아래로 내리면 FAB가 Hide가 되고, 위로 올리면 FAB가 Show가 된다.
(그러나 ScrollDirection.idle이 먹히지 않아... 다른 방법을 써야했다. 이유는 실력부족으로 나중엔 꼭 알아야할 거 같다.)

NotificationListener 이용하기

플러터 문서를 이리저리 보던 중에 알림을 보낼 수 있는 NotificationListener를 찾게 되었고 뒤에서 스크롤 노티피케이션은 처리하고자 하는 유형으로 생각하면 된다고 한다.

NotificationListener는 나중에 추가적으로 공부하기로 마음을 먹고, 빠르게 사용해보았다.

알림이 처리 되었는 지는 onNotification을 사용하며 return true/false로 나타낸다.

예시를 말씀드리자면,

  return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification notification) {
        myScrollNotification(notification);
        return false;
      },
  //child: Listview.
  // 리스트뷰를 NotificationListener로 묶어주고 사용한다.. 지금은 설명을 위해 child를 자세히 쓰진 않았다.
  );
  

ScrollNotification notification을 onNotification 안에 넣어서 myScrollNotification라는 메소드를 생성한다.
myScrollNotification(notification) 처럼 notification을 변수로 넘겨준다.

글이 길어진만큼 빠르게 설명해보겠다.

  void hideFloatButton() {
    setState(() {
      _visibleButton = false;
    });
  }

  void showFloatButton() {
    setState(() {
      _visibleButton = true;
    });
  } 
  myScrollNotification(notification) {
    if (notification is UserScrollNotification) {
// 문서를 봤을 때엔 A User ScrollNotification, with a User ScrollNotification.direction of
 // Scroll Direction.idle.이라는 말을 보고 idle 상태일 때 쓰인다는 생각을 하여 사용!..
      showFloatButton();
    } else {

      hideFloatButton();
    }
  }
     // notification is ScrollStartNotification(스크롤을 시작하면 발생) 
  // OverscrollNotification 스크롤을 시작후 움직일때 발생(Android)
  // ScrollEndNotification 스크롤이 끝났을때 발생
  // ScrollUpdateNotification 스크롤을 시작후 움직일때 발생(ios)
  

위의 예처럼 notification이 UserScrollNotification => 스크롤이 움직이지 않을 때만 FAB = Show 하게 구현했다.

개발을 하면서도 벨로그 작성은 처음이라 부족하겠지만 언젠간 좋아질 거라 믿는다.

위의 설명이 부족해서 이해가 안되신다면 요청 시 소스코드를 공유드릴 예정입니다.

The End

profile
즐거움을 만드는 사람

0개의 댓글