반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Game js
- Three-fiber
- web track
- Babel standalone
- swagger-typescript-api
- FirebaseAnalytics
- Three js
- Completer
- Image Resize typescript
- uint8array
- androidId
- RouteObserver
- userevent_tracker
- Prism.js
- babel
- REST API
- Flutter
- jszip
- KakaoMap
- Raycasting
- code editor
- react
- Excel
- webrtc
- identifierForVender
- methodChannel
- typescript
- uint16array
- Redux
- node
Archives
- Today
- Total
Never give up
Flutter - Listview with ScrollController 본문
반응형
Listview를 사용하다보면 스크롤이 맨 위 혹은 아래에 도달했을때
특정 동작을 해야되는 경우가 있는데, ScrollController를 이용하면 간단하게 해결 가능합니다
(해당 소스코드는 맨 아래에 도달했을 때 FAB을 숨기는 동작을 함)
메인
class ListTestScreen extends StatefulWidget {
@override
_ListTestScreenState createState() => _ListTestScreenState();
}
class _ListTestScreenState extends State<ListTestScreen> {
ScrollController _controller;
@override
void initState() {
super.initState();
_controller = ScrollController();
_controller.addListener(_scrollListener);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
_scrollListener() {
var _data = Provider.of<VisibilityData>(context, listen: false);
if (_controller.offset >= _controller.position.maxScrollExtent &&
!_controller.position.outOfRange) {
_data.setVisible(false);
} else {
_data.setVisible(true);
}
}
@override
Widget build(BuildContext context) {
return Consumer<VisibilityData>(builder: (context, value, child) {
return Scaffold(
appBar: AppBar(title: Text('Scroll test')),
body: ListView.builder(
controller: _controller,
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
child: Text('${index + 1}'),
),
title: Text('2 x $index = ${index * 2}'),
);
}),
floatingActionButton: Visibility(
visible: value.getVisible,
child: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {},
),
),
);
});
}
}
데이터
class VisibilityData extends ChangeNotifier {
bool _visible = true;
bool get getVisible => _visible;
void setVisible(bool value) {
_visible = value;
notifyListeners();
}
}
하지만 위와 같이 else 부분에서 처리를 해버리면 성능상 단점이 생길 수 있습니다
실제로 print를 해보면 setVisible이 1번 이상 불리게 되고
notifyListeners() 또한 여러번 불리게 되어 성능 하락 및 에러를 발생시킬 수 있습니다
그래서 조금 더 개선을 시켜보면
_scrollListener() {
var _data = Provider.of<VisibilityData>(context, listen: false);
if (_controller.offset >= _controller.position.maxScrollExtent &&
!_controller.position.outOfRange) {
_data.setVisible(false);
} else if(_controller.offset < _controller.position.maxScrollExtent &&
!_data.getVisible){
_data.setVisible(true);
}
}
다음과 같이 표현할 수 있습니다
offset이 화면 최하단보다 위에 있고, visible false 상태일 때만 visible true를 설정하면 더 좋을거 같습니다
추가로 setState되는 과정에서 Listview가 갱신되는 구조로 코딩을 하셨다면
해당 부분은 StreamBuilder를 이용해서 처리하면 될거 같습니다
반응형
'Flutter' 카테고리의 다른 글
Flutter - StatefulWidget Lifecycle (0) | 2020.08.03 |
---|---|
Flutter - Listview with Listener (0) | 2020.08.03 |
Flutter - AnimatedBuilder with transition (0) | 2020.08.03 |
Flutter - Indexed Stack with Provider (5) | 2020.08.03 |
Flutter - Splash Screen(Loading screen) (0) | 2020.08.03 |
Comments