본문 바로가기
flutter

[flutter] 페이지네이션(무한 스크롤) 커스터마이징 -로딩, 에러, infinite_scroll_pagination

by 슈크림 붕어빵 2023. 7. 7.

이전 포스트에서는 infinite_scroll_pagination을 이용해 페이지네이션을 구현했다. 

구현 자체는 이전 포스트에서 다룬다.

 

에러가 떴을 때, 화면 창이 사용하는 ui와 맞지 않아서 커스터마이징을 진행하려고 했다..

item별로 로딩중일 때, 로딩을 완료했을 때, 에러가 떴을 때를 커스터마이징 할 수 있다.

data를 받아오는 전체 오류인 줄 알았으나 아니었고 상품 카드의 가로 세로 비율을 고정해야하나 카드가 ui의 가로를 전부 사용해야하고 폰마다 card비율이 달라지므로 적용하지는 않았다.

다만 다음에 사각형 모양을 grid모양으로 만들 때 유용할 것 같아서 적어두겠다.

 

전체적으로 api를 가져올 때 오류가 나는 경우는 다음 포스트에서 다룬다.

 

이와 같이 상품별, 즉 item별로 로딩중을 구현하는 방법이다. 

설명상으로 에러가 뜬다는게 전체를 받아오지 못한 경우를 설정한다고 생각했으나.. item하나하나를 설정하는 법이다. 

 

Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(top: widget.topPadding),
      child: Center(
        child: CustomScrollView(slivers: [
          PagedSliverBuilder<int, Product>(
            pagingController: _pagingController,
            builderDelegate: PagedChildBuilderDelegate<Product>(
              itemBuilder: (context, item, index) => ProductCard(
                product: item,
              ),
            ),
            completedListingBuilder: (
              context,
              itemBuilder,
              itemCount,
              noMoreItemsIndicatorBuilder,
            ) =>
                SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2, // 그리드의 열 수를 2개로 설정
                crossAxisSpacing: 10.0, // 아이템 간의 가로 간격을 10.0으로 설정
                mainAxisSpacing: 10.0, // 아이템 간의 세로 간격을 10.0으로 설정
                childAspectRatio: 0.75, // 각 아이템의 가로 너비와 세로 높이의 비율을 0.75로 설정
              ),
              delegate: SliverChildBuilderDelegate(
        		itemBuilder,
            	childCount: itemCount,
      			),
            ),
            loadingListingBuilder: (
              context,
              itemBuilder,
              itemCount,
              progressIndicatorBuilder,
            ) =>
                SliverGrid(
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2, // 그리드의 열 수를 2개로 설정
                      crossAxisSpacing: 10.0, // 아이템 간의 가로 간격을 10.0으로 설정
                      mainAxisSpacing: 10.0, // 아이템 간의 세로 간격을 10.0으로 설정
                      childAspectRatio:
                          0.75, // 각 아이템의 가로 너비와 세로 높이의 비율을 0.75로 설정
                    ),
                    delegate: SliverChildBuilderDelegate(
                      (context, index) => Center(
                        child: CircularProgressIndicator(), // 프로그레스 인디케이터를 표시
                      ),
                      childCount: 2,
                    )),
            errorListingBuilder: (
              context,
              itemBuilder,
              itemCount,
              errorIndicatorBuilder,
            ) =>
                SliverGrid(
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2, // 그리드의 열 수를 2개로 설정
                      crossAxisSpacing: 10.0, // 아이템 간의 가로 간격을 10.0으로 설정
                      mainAxisSpacing: 10.0, // 아이템 간의 세로 간격을 10.0으로 설정
                      childAspectRatio:
                          0.75, // 각 아이템의 가로 너비와 세로 높이의 비율을 0.75로 설정
                    ),
                    delegate: SliverChildBuilderDelegate(
                      (context, index) => Center(
                        child: Text("상품을 불러올 수 없습니다."), // 프로그레스 인디케이터를 표시
                      ),
                      childCount: 1,
                    )),
          ),
        ]),
      ),
    );
  }

이와같이 CustomScrollView로 감싸고 sliver로 자식들을 둔다. 각 상황에 맞는 위젯을 달아준다. 로딩이 완료된 경우에는 itembuilder를 이용한다. childCount로는 위젯의 수를 설정할 수 있다.