HugeListView는 매우 많은 수의 항목을 포함하는 리스트를 효율적으로 처리할 수 있도록 설계된 고성능 스크롤 위젯입니다. 보이는 위젯만 빌드함으로써 렌더링을 최적화하여 메모리 사용량을 줄이고 반응성을 향상시킵니다. 긴 메시지 스레드, 데이터 그리드 또는 광범위한 카탈로그와 같이 수천 또는 수백만 개의 항목을 부드럽게 스크롤해야 하는 애플리케이션에 적합합니다. Flutter의 지연 로딩 원칙에 기반하여 구현되어 거대한 데이터셋에서도 최소한의 오버헤드를 보장합니다. 이 패키지는 Android, iOS, Web, macOS, Windows 및 Linux를 포함한 모든 주요 플랫폼을 지원합니다.
사용 사례
앱에서 대규모 데이터 세트 표시
수백만 개의 항목을 포함하는 스크롤 가능한 목록 만들기
효율적인 데이터 그리드 구축
무한 스크롤 인터페이스 구현
긴 메시지 스레드에 대한 성능 최적화
주요 기능
거대한 목록의 효율적인 렌더링
보이는 항목만을 위한 지연 로딩
낮은 메모리 사용량
크로스 플랫폼 호환성
부드러운 스크롤 경험
사용자 지정 항목 빌더를 지원합니다
적합한 대상
고성능 리스트가 필요한 개발자
광범위한 데이터 세트를 가진 앱
확장 가능한 UI 컴포넌트
성능 중심 애플리케이션
대량의 콘텐츠를 포함한 웹 및 모바일 앱
고려 사항
신중한 상태 관리가 필요할 수 있습니다
작은 목록에는 적합하지 않습니다
사용자 정의에는 추가 코드가 필요할 수 있습니다
핵심 위젯에 비해 문서가 제한적
다른 스크롤 컨트롤러와 통합할 때의 잠재적 복잡성
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Huge ListView
A performant ListView that can handle any number of items with ease. Unlike other infinite list approaches,
it doesn't just add new items to the list, growing to huge sizes in the end, but has a fixed size cache that
only keeps a handful of pages (in other words, a few hundred items at most) all the time, discarding old pages
as new ones come in. The list asks for a pageful of items at once, in an async function, expecting to receive
a Future<List<T>> of your items.
This approach means that the actual number of items in the list makes no difference. Hundreds of thousands or
even millions of items are all the same. You never have to read and keep all of them in memory at the same time.
Instead of a regular ListView, it uses a ScrollablePositionedList inside that makes it possible to scroll
to specific items rather than scroll positions. The items don't have to be of uniform height, their size differences
don't affect performance at all. This list implementation, however, doesn't play nice with the regular Scrollbar,
so we use our own DraggableScrollbar instead. This way we can support both a scrollbar and the usual position-based
scrolling as well.
staticconstint PAGE_SIZE = 12;
final listKey = GlobalKey<HugeListViewState>();
final scroll = ItemScrollController();
final controller = HugeListViewController(totalItemCount: 999999);
HugeListView<MyDataItem>(
/// Only needed if you expect to make use of its [setPosition] function.
key: listKey,
/// Only needed if you expect to make use of its [jumpTo] or [scrollTo] functions (the thumb expects it, though).
scrollController: scroll,
/// Only needed if you expect to provide the total count of items.
listViewController: controller,
/// Size of the page. [HugeListView] only keeps a few pages of items in memory any time.
pageSize: PAGE_SIZE,
/// Index of an item to initially align within the viewport.
startIndex: 0,
/// Called to load items for the list with the specified [pageIndex].
pageFuture: (page) => _loadPage(page, PAGE_SIZE),
/// Called to build an individual item with the specified [index].
itemBuilder: (context, index, MyDataItem entry) {
returnText(entry.name);
},
/// Called to build the thumb. One of [DraggableScrollbarThumbs.RoundedRectThumb], [DraggableScrollbarThumbs.ArrowThumb],/// [DraggableScrollbarThumbs.SemicircleThumb] or build your own.
thumbBuilder: DraggableScrollbarThumbs.SemicircleThumb,
/// Background color of scroll thumb, defaults to white.
thumbBackgroundColor: Colors.white,
/// Drawing color of scroll thumb, defaults to gray.
thumbDrawColor: Colors.grey,
/// Height of scroll thumb, defaults to 48.
thumbHeight: 48,
/// Called to build a placeholder while the item is not yet availabe.
placeholderBuilder: (context, index) => <some Widget>,
/// Called to build a progress widget while the whole list is initialized.
waitBuilder: (context) => <some Widget>,
/// Called to build a widget when the list is empty.
emptyBuilder: (context) => <some Widget>,
/// Called to build a widget when there is an error.
errorBuilder: (context, error) => <some Widget>,
/// Event to call with the index of the topmost visible item in the viewport while scrolling./// Can be used eg. to display the current letter of an alphabetically sorted list.
firstShown: (index) {},
/// The axis along which the list view scrolls. Defaults to [Axis.vertical].
scrollDirection: Axis.vertical,
/// The amount of space by which to inset the list.
padding: EdgeInsets.all(6.0),
/// Whether the scroll thumb slides out when not used, defaults to always visible.
alwaysVisibleThumb: false,
/// How quickly the scroll thumb animates in and out. Ignored if `alwaysVisibleThumb` is true./// Defaults to kThemeAnimationDuration.
thumbAnimationDuration = constDuration(milliseconds: 300),
/// How long the scroll thumb stays visible before disappearing. Ignored if `alwaysVisibleThumb` is true./// Defaults to 1 second.
thumbVisibleDuration = constDuration(milliseconds: 600),
/// Optional external LruMap to be used for cache.finalLruMap<int, HugeListViewPageResult<T>>? lruMap;
);
You have to pass a list of your items to pageFuture, for instance, given a list named data:
Future<List<MyDataItem>> _loadPage(int page, int pageSize) async {
int from = page * pageSize;
int to = min(data.length, from + pageSize);
return data.sublist(from, to);
}
The waitBuilder can be a simple centered CircularProgressIndicator but a nicer idea is
to provide a placeholderBuilder that is a mockup of the data to arrive. Many apps and sites
use gray horizontal bars instead of the actual text during loading. As an example,
here is a simple function that creates such a bar with randomly varying length: