##FAB Hide/Show
정리해야할 것은 참 많은데, 어쩌다보니 FAB Hide/Show를 정리하게 되었다.
FAB = FloatingActionButton => appBar / body / bottomNavigationBar처럼 Scaffold의 아이(?)
앱을 하나 만들면서, FAB를 Hide 시키기 위해서 어떻게 할 지 공식문서를 쥐잡듯이 보다보니.. 1가지 정답을 찾았다. (물론 정답은 많다!)
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를 주면 될 것이다.
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는 나중에 추가적으로 공부하기로 마음을 먹고, 빠르게 사용해보았다.
알림이 처리 되었는 지는 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 하게 구현했다.
개발을 하면서도 벨로그 작성은 처음이라 부족하겠지만 언젠간 좋아질 거라 믿는다.
위의 설명이 부족해서 이해가 안되신다면 요청 시 소스코드를 공유드릴 예정입니다.