반응형
시작하기
Flutter 의 ListView 위젯과 GetX를 이용해 마지막 리스트에 도달 하면 추가적인 데이터를 서버에서 가지고 오는 UI를 구현합니다. (GetX 대신 Provider나 StatefullWedget으로 변경해도 됩니다.)
GetX 사용을 위한 기본 설정들
💡
GetX를 사용하지 않는경우 해당항목 생략
- pubspec.yaml dependencies 추가
get: ^4.1.4
- main.dart MaterialApp → GetMaterialApp 으로 변경
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialBinding: AppBinding(),
home: Scaffold(
appBar: AppBar(
title: Text('Flutter!'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: ElevatedButton(
onPressed: () {
Get.to(() => InfiniteScrollView());
},
child: Text('Infinite Scroll View'),
),
),
],
),
),
);
}
}
- AppBinding
class AppBinding extends Bindings {
@override
void dependencies() {
Get.put(InfiniteScrollController());
}
}
Infinite Scroll Controller
💡
GetX를 사용해 구현했습니다.
class InfiniteScrollController extends GetxController {
var scrollController = ScrollController().obs;
var data = <int>[].obs;
var isLoading = false.obs;
var hasMore = false.obs;
@override
void onInit() {
_getData();
this.scrollController.value.addListener(() {
if (this.scrollController.value.position.pixels ==
this.scrollController.value.position.maxScrollExtent &&
this.hasMore.value) {
_getData();
}
});
super.onInit();
}
_getData() async {
isLoading.value = true;
await Future.delayed(Duration(seconds: 2));
int offset = data.length;
var appendData = List<int>.generate(10, (i) => i + 1 + offset);
data.addAll(appendData);
isLoading.value = false;
hasMore.value = data.length < 30;
}
reload() async {
isLoading.value = true;
data.clear();
await Future.delayed(Duration(seconds: 2));
_getData();
}
}
코드 설명
- 리스트뷰의 상태를 감지하기 위한
ScrollController
ScrollController
의 position 값을 이용해 가장 마지막 행에 도달했는지 확인
- 마지막 행에 도달한 경우
_getData
를 실행하는addListener
추가
- 리스트뷰에 표시할 데이터인
data
- 실제 서버에서 데이터를 가지고 오는 것을 시뮬레이션 하기위해 강제로 2초의 딜레이 설정
- 가지고 온 데이터의 총 갯수가 30개 이상이라면 더이상 데이터가 없는 것으로 판단
- 로딩중 이나, 다음 데이터 존재여부체크를 위한
isLoading
,hasMore
Infinite Scroll View
class InfiniteScrollView extends GetView<InfiniteScrollController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Infinite Scroll'),
),
body: Obx(
() => Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.separated(
controller: controller.scrollController.value,
itemBuilder: (_, index) {
print(controller.hasMore.value);
if (index < controller.data.length) {
var datum = controller.data[index];
return Material(
elevation: 10.0,
child: Container(
padding: const EdgeInsets.all(10.0),
child: ListTile(
leading: Icon(Icons.android_outlined),
title: Text('$datum 번째 데이터'),
trailing: Icon(Icons.arrow_forward_outlined),
),
),
);
}
if (controller.hasMore.value || controller.isLoading.value) {
return Center(child: RefreshProgressIndicator());
}
return Container(
padding: const EdgeInsets.all(10.0),
child: Center(
child: Column(
children: [
Text('데이터의 마지막 입니다'),
IconButton(
onPressed: () {
controller.reload();
},
icon: Icon(Icons.refresh_outlined),
),
],
),
),
);
},
separatorBuilder: (_, index) => Divider(),
itemCount: controller.data.length + 1,
),
),
),
);
}
}
코드설명
- GetX의
Obx
를 이용해 Reactive처리
- 기본적인
ListView
를 구성하되,itemCount
를 실제데이터 갯수 + 1로 지정- 추가된 행에서
ProgressIndicator
혹은 데이터없음 안내 표시
- 추가된 행에서
실제 동작 화면
소스 링크
flutter_infinite_scroll
Instantly share code, notes, and snippets. You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or window. Reload to refresh your session. Reload to refresh your session.

empering/flutter_smaple
A new Flutter project. This project is a starting point for a Flutter application. A few resources to get you started if this is your first Flutter project: For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.
반응형
'Flutter' 카테고리의 다른 글
Flutter 2.2 새롭게 추가된 것들 (0) | 2021.05.21 |
---|---|
Flutter Null Safety 적용안된 package 직접 Migration 하기 (pub.dev package) (0) | 2021.05.16 |
Flutter Engage Extended Seoul Goods! (0) | 2021.05.12 |
Flutter 앱출시 방법 (0) | 2021.04.15 |
댓글