대량의 데이터를 페이지 단위로 나누어 표시하는 기술.
대량의 데이터를 작은 페이지로 나누어서 사용자에게 보여주므로 한 번에 모든 데이터를 로드하지 않아
성능을 향상시키고 메모리 사용량을 줄일 수 있습니다.
필요한 만큼의 데이터를 서버에서 요청하므로 네트워크 트래픽을 최적화할 수 있습니다.
작은 페이지 단위로 나누어 사용하므로 데이터를 처리하기가 더 편리해집니다.
ex ) 특정 페이지만 새로고침하는 경우 해당 페이지만 데이터 수정 및 업데이트를 진행.
사용자가 빠르게 스크롤할 경우, 중간에 데이터의 누락 및 중복이 발생하거나 급속도로 연속적인 서버 호출이 발생할 수 있습니다.
각 페이지가 시간에 따라 변경될 수 있으므로, 사용자에게 일관된 데이터를 제공하기 위해 적절한 캐싱이나 관리가 필요합니다.
⚠️ 위와 같은 주의점이 있으므로 필요에 따라 최적화가 필요합니다!
구현하는 방법에는 여러 가지가 있지만 그 중 아래에서 구현할 방법은 가장 일반적인 방법인 ListView.builder 와 GridView.builder 중 본 예시에서는 ListView를 이용해 진행합니다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Pagination 예시'),
),
body: PaginationTest(),
),
);
}
}
class PaginationTest extends StatefulWidget {
_PaginationTestState createState() => _PaginationTestState();
}
class _PaginationTestState extends State<PaginationTest> {
List<String> items = List.generate(15, (index) => '${index + 1}번째 위젯');
final ScrollController _scrollController = ScrollController();
bool isLoading = false; // 다중 로드를 막기 위한 변수
void initState() {
super.initState();
_scrollController.addListener(_onScroll);
}
void dispose() {
_scrollController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemCount: items.length + 1, // 로딩 인디게이터 표시를 위한 추가
itemBuilder: (context, index) {
if (index < items.length) {
return ListTile(
title: Text(items[index]),
);
} else {
return isLoading
? const CircularProgressIndicator()
: const SizedBox();
}
},
);
}
void _onScroll() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
// 최대 스크롤까지 도달 시 새로운 데이터 로드
_loadData();
}
}
Future<void> _loadData() async {
if (!isLoading) {
setState(() {
isLoading = true;
});
await Future.delayed(Duration(seconds: 4)); // 로딩 인디게이터 표시를 위한 딜레이
List<String> newItems = List.generate(
10, (index) => '새로 추가 된 ${items.length + index + 1}번째 위젯');
setState(() {
items.addAll(newItems);
isLoading = false;
});
}
}
}
스크롤이 끝에 도달할 때마다 _loadData
함수를 호출하여 새로운 데이터를 추가합니다.
isLoading
변수를 이용해 데이터를 가져오는 중이라면 로딩 인디케이터 표시와 함께 중복 호출을 방지합니다.
개발자로서 배울 점이 많은 글이었습니다. 감사합니다.