앱 만들기 프로젝트/Flutter

Flutter - 6.7 ListView

지나가는물리학부생 2024. 11. 26. 20:10
반응형

FutureBuilder 부분을 다음과 같이 바꾸자.

      body: FutureBuilder(
        future: webtoons,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView(
              children: [
                for (var webtoon in snapshot.data!) Text(webtoon.title)
              ],
            );
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      ),

단순한 코드이다.
데이터가 아직 없는 경우 $\rightarrow$ 로딩화면
데이터가 들어온 경우 $\rightarrow$ snapshot에 들어온 데이터를 ListView로 보여주기.

for (var webtoon in snapshot.data!) 
이 부분은 collection for을 사용한 것이다. 자세한 것은...https://want-to-work-life-balance.tistory.com/entry/Dart-23-Collection-For

 

Dart - 2.3 Collection For

Dart 공식 문서에 따르면...(https://dart.dev/guides/language/language-tour#collection-operators) Dart also offers collection if and collection for, which you can use to build collections using conditionals (if) and repetition (for). 컬렉션을 구

want-to-work-life-balance.tistory.com

그리고, snapshot.data! 이렇게 '!'를 사용한 것이 보인다. 이것은 snapshot.data가 null값이 아니라고 하는 의미이다.
null값이 가능한 변수이지만, snapshot에 데이터가 있을 경우에만 실행되는 부분이기 때문에 null값일 수가 없다.
따라서 null값이 아니라고 말하는 것이다.

이렇게 하면 자동으로 모든 데이터를 한번에 출력하고, 스크롤까지 자동으로 만들어진다.

하지만, 한번에 모든 데이터를 로딩해서 보여주기 때문에 비효율적이다.
사용자가 보고 있는 부분만 로딩하면 된다.
이럴 때는... ListView.builder를 사용한다.

          if (snapshot.hasData) {
            return ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                var webtoon = snapshot.data![index];
                return Text(webtoon.title);
              },
            );

itemBuilder 는 무조건 사용해야 한다.
1. 스크롤을 가로로 변경
2. 아이템의 개수는 snapshot 데이터의 개수로 설정
3. itemBuilder에서 알아서 index를 이용해서 보고 있는 부분만 로딩을 함.

이걸 알아서 해준다니... 너무 좋잖아"
하지만, 여기에서는 데이터가 모두 이어져서 출력된다.

조금 더 개선된 것을 해보자. ListView.separated를 사용하자.

            return ListView.separated(
              scrollDirection: Axis.horizontal,
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                var webtoon = snapshot.data![index];
                return Text(webtoon.title);
              },
              separatorBuilder: (context, index) => const SizedBox(width: 20),
            );

separatorBuilder 를 필수로 써야 한다.
그래서, ListView.builder에서 separatorBuilder만 추가한 상태이다.
단순하다. List안에 있는 인자들의 사이에 SizedBox(width: 20) 를 넣어서 구분한다는 것이다.
그래서 이번에는 웹툰 제목들이 떨어져서 출력되는 것을 확인할 수 있을 것이다.

이게 기본 패키지에 있는 거라고?

참고로, main.dart 파일에

return MaterialApp(
scrollBehavior: const MaterialScrollBehavior().copyWith(
dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
},
),
home: HomeScreen(),
);

이렇게 추가해주면 웹과 안드로이드 모두 스크롤이 작동한다고 하더라.
nomadcoders 강의의 sjjoseph106님의 댓글을 참고했다.

반응형