[Flutter] 무한 스크롤 만들기(2) - Horizontal

Tyger·2022년 12월 29일
1

Flutter

목록 보기
4/64
post-custom-banner

무한 스크롤 만들기 - Horizontal

스크롤 인디케이터 - Vertical
스크롤 인디케이터 - Horizontal
무한 스크롤 만들기 - Vertical
무한 스크롤 만들기 - PageView

이전 시간에는 Vertical 구조의 무한 스크롤 기능을 만들어 봤는데, 이번에는 이어서 Horizontal 구조의 무한 스크롤을 만들어 보도록 하겠다.

여기서도 데이터 파일로 이전 시간과 동일한 이미지를 사용하였고, 함수도 그대로 사용하였다.

Data

Lorem Picusm

Flutter

State Management - Provider

UI

Horizontal 구조의 ListView를 생성 하려면 필수로 높이 값을 넣어주어야 한다.
높이 값이 없으면 해당 리스트 뷰가 어느 정도의 포지션을 차지해야 하는지 몰라서 에러가 발생한다.

여기서도 앞서 살펴본 Vertical 구조의 UI와 똑같이 마지막 item일 경우에 로딩 바를 보여줄 수 있도록 개발하였다.

Padding(
            padding: const EdgeInsets.only(top: 24),
            child: SizedBox(
              height: 200,
              child: NotificationListener<ScrollUpdateNotification>(
                onNotification: (ScrollUpdateNotification notification) {
                  value.listner(notification);
                  return false;
                },
                child: ListView(
                  scrollDirection: Axis.horizontal,
                  children: <Widget>[
                    ...value.items.map((e) => Padding(
                          padding: const EdgeInsets.only(left: 20),
                          child: SizedBox(
                            child: Image.network(
                              e,
                              width: 200,
                              height: 200,
                              fit: BoxFit.cover,
                            ),
                          ),
                        )),
                    if (value.isMore) ...[
                      const Padding(
                        padding: EdgeInsets.symmetric(horizontal: 20),
                        child: SizedBox(
                          width: 200,
                          height: 300,
                          child: Center(
                            child: CircularProgressIndicator(
                              color: Colors.deepOrange,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ],
                ),
              ),
            ),
          ),

Provider

아래 상태관리는 어전에 작성한 글과 동일하기에 복사해왔다.


무한 스크롤 로직을 만들기 위해 리스트 뷰에서 보여줄 items라는 List 타입의 변수와 현재 몇 번째 까지 호출을 했는지를 확인하기 위한 currentIndex 변수 그 다음 로딩 바를 구현하기 위해 불리언 값으로 isMore 변수를 생성해 주었다.

  List<String> items = [];
  int currentIndex = 0;
  bool isMore = false;

페이지에 접근시 최초 시작하는 함수를 만들었다.

해당 함수를 보면 반복문을 사용하여 items 변수에 1씩 증가한 url 값을 넣어주었다.

  Future<void> started() async {
    for (int i = 0; i < 20; i++) {
      items.add('https://picsum.photos/id/$i/200/200');
    }
    currentIndex = 20;
  }

스크롤에 의해서 아이템을 더 불러오기 위한 함수를 만들었다.

로딩 바를 확실히 보여주기 위해 3초간의 딜레이를 발생시킨 후 items에 20개의 url을 더 담아주는 로직이다.

함수 상단 부분에 isMore라는 함수를 활용하여 스크롤 포지션에 의해 아이템을 마구잡이로 불러오는 것을 방지하고 있다.

Future<void> _addItem() async {
    if (!isMore) {
      isMore = true;
      notifyListeners();
      Future.delayed(const Duration(milliseconds: 3000), () {
        for (int i = 0; i < 20; i++) {
          items.add('https://picsum.photos/id/${i + currentIndex}/200/200');
        }
        currentIndex = currentIndex + 20;
        isMore = false;
        notifyListeners();
      });
    }
  }

listener라는 함수에 ScrollUpdateNotification 값을 받아와 해당 뷰의 최대 스크롤 높이 값의 85프로가 도달하면 위에서 만들어준 _addItem() 함수를 호출시키는 로직이다.
listener 함수는 위에서 만들었던 NotificationListener 위젯 안에서 실행될 수 있도록 추가해주면 된다.

Git

https://github.com/boglbbogl/flutter_velog_sample/tree/main/lib/infinity_scroll

Result

마무리

이렇게 Vertical / Horizontal 구조의 무한 스크롤에 대해서 알아보았다.

다음 시간에는 PageView 구조에서 무한 스크롤을 만드는 기능에 대해서 작성하도록 하겠다.

profile
Flutter Developer
post-custom-banner

0개의 댓글