body: FutureBuilder(
future: webtoons, // await효과
builder: (context, snapshot) {
//snapshot으로 future의 상태를 알 수있다. 오류인지, 값을 받았는지
if (snapshot.hasData) {
return ListView(
children: [
for (var webtoon in snapshot.data!) Text(webtoon.title),
//! == snapshot는 data를 가지고있다고 확신을 주는 것
],
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
위 방식은 for문을 통해서 한번에 모든 데이터를 불러오고 리스트화한다.
한번에 데이터를 로딩하는 것은 메모리를 많이 사용하게 되고, 메모리가 죽을 수도 있다. 따라서 사용자가 보고 있는 섹션만 로딩해야한다.
그래서 다음방식을 사용한다
builder()는 많은 옵션을 가지고 있다.
그 중에 몇개만 보면
ListView.builder는 ListView보다 훨씬 최적화 됐다.
사용자가 볼 수없는 아이템은 빌드 안하니까.
모든 아이템을 한번에 만드는 대신, 만드려는 아이템에 itemBuilder함수를 실행함.그러면 여기서 build되는 아이템에 index로 접근할 수있음.
아래 코드에서 snapshot.data는 List기 때문에 인덱스로 접근할 수 있음.
if (snapshot.hasData) {
return ListView.builder(
itemBuilder: (context, index) {
var webtoon = snapshot.data![index];
return Text(webtoon.title);
},
scrollDirection: Axis.horizontal,
itemCount: snapshot.data!.length,
);
}
return const Center(
child: CircularProgressIndicator(),
);

builder는 현재 사용자에게 보여지는 화면만 build한다.
예를 들어 전체 리스트 크기가 40이더라도 사용자에게 보이는 개수가 10개면 10개의 item만 build하게 된다.
만약 사용자가 scroll해서 보여지는 아이템이 달라지게 되면 추가로 build를 함으로써 화면에 출력한다.
그러면 이전에 build했던, 현재는 화면에 출력되지 않는 아이템의 행방은?
나중에 사용자가 다시 되돌아가게 되면 이전에 build했던 item을 재활용한다.
separated는 위젯을 리턴해야하는 함수다.
그리고 그 위젯은 리스트 아이템 사이에 렌더된다.
왜? 아이템들을 구분하기 위해서
separatorBuilder: (context, index) => const SizedBox(
width: 20,

각 아이템들 사이에 sizedbox를 넣은 것임
혹시나 아이템이 만들어지는 모습을 보고 싶다면 print(index);를 이용하자