view에 스크롤이 중첩된다면 lazy loading을 어떻게 줄 수 있을까?

su.log·2023년 8월 25일
0

flutter에서 ui작업을 하다보면 SingleChildScrollView나 ListView와 같은 전체 위젯을 감싸서 페이지를 전체 스크롤링하는 경우들이 있다.
ListView 위젯이 전체를 감싸고 위젯 내부에 child로 또 ListView.builder가 들어가는 경우도 있다. 만약 해당 페이지에서 인피니티 스크롤을 구현하고 싶다면 어떻게 구현하면 좋을까?

먼저 pub.dev 인기 패키지인 infinite_scroll_pagination을 이용해 보았다.

static const _pageSize = 20;

  Future<void> _fetchData(int pageKey) async {
    try {
      final newItems = await CallApi.getImages(pageKey, _pageSize);
      final isLastPage = newItems.length < _pageSize;
      if (isLastPage) {
        _pagingController.appendLastPage(newItems);
      } else {
        final nextPageKey = pageKey + newItems.length;
        _pagingController.appendPage(newItems, nextPageKey);
      }
    } catch (error) {
      _pagingController.error = error;
    }
  }
   PagedListView<int, CharacterSummary>(
        pagingController: _pagingController,
        builderDelegate: PagedChildBuilderDelegate<ImageList>(
          itemBuilder: (context, item, index) => ImageListItem(
            image: item,
          ),
        ),
      );

사용법은 간단하지만 원하는대로 작동하지는 않았다.
스크롤을 다 내리기도 전에 fetchData를 호출해버려서 UX가 원하는대로 동작하지 않는다.
이유는 중첩된 리스트로 어떤 리스트에 초점을 맞춰서 동작해야 할지 모르는것이 아닌가 싶다.

그렇다면 어떤방법으로 해결하면 좋을까?
나는 SingleChildView에 ScrollController를 주는 방법을 선택했다.

 scrollController.addListener(() {
      if (scrollController.position.pixels ==
              scrollController.position.maxScrollExtent &&
          isReloadHistoryData[currentTab.value]) {
        if (currentTab.value != HistoryMissionType.recommend) {
          _featchData();
        }
      }
    });

위와 같은 방법으로 addListener를 활용하였고 전체 스크롤이 페이지 끝에 닿으면
fetchData를 호출하여 infinityScroll을 구현하였다.
문제없이 원하는대로의 UX가 나왔고 package를 사용하는것보다 간단한 방식으로 구현 가능했다.

0개의 댓글