오늘은 futureBuilder에 대해서 적어보려고 한다.
flutter에서 데이터를 받아올 와 출력할 때, 비동기식 통신방법을 이용하고 싶으면 futureBuilder 위젯을 이용하면 된다.
futureBuilder는 데이터를 불러오기 전 데이터와 상관 없는 부분과 로딩 화면을 먼저 출력시키고 데이터를 다 불러온 뒤에 나머지 화면을 출력시켜주는 역할을 한다.
futureBuilder를 얘기하기 전에 future의 개념부터 간단히 적고 넘어가려고 한다.
future는 지금은 데이터가 없지만 미래에 여기에 데이터가 담길거야! 라고 말해주는 것과 같다.
futureBuilder 에는 future와 builder 값이 필요하다
body:FutureBuilder(
future:a.
builder:(context, snapshot){
if(snapshot.hasData) {
return const Text("Data !");
}
return Text('Loading');
}
)
future는 비동기로 동작하는 함수를 넣어주면 된다.
future 객체는 작업이 완료되면 결과를 가지고 올 수 있다.
builder는 인자로 context와 snapshot를 갖는데, context는 현재 위젯의 위치와 상태에 대한 정보를 제공하는 객체이다.
context는 위젯 트리에서 현재 위젯이 어디에 위치하고 있는지, 어떤 테마가 적용되어 있는지, 어떤 언어가 설정되어 있는지 등의 정보를 알려준다.
snapshot은 future 객체의 현재 상태를 의미한다. future 객체가 값을 가지고 있는 상태인건지, 오류 또는 작업이 아직 완료되지 않았는지를 판단하여 각 다른 위젯을 반환할 수 있게 한다.
만약에 받아오는 데이터가 여러개라면 ???? future.wait을 사용하면 된다.
구현 방식은 futurebuild와 비슷하지만 wait는 값들을 배열에 담는다는 차이가 있다.
아래는 완성된 코드이다.
final Future<List<MovieModel>> popularMovies =
MyHomePageState.getTodayMovie();
// 데이터가 받아와지면, popularMovies라는 List에 담길거다
final Future<List<MovieModel>> comingMovies =
MyHomePageState.getComingMovie();
final Future<List<MovieModel>> playingMovies =
MyHomePageState.getPlayingMovie();
...
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: FutureBuilder(
future: Future.wait([popularMovies, comingMovies, playingMovies]),
builder: (context, AsyncSnapshot<List<List<MovieModel>>> result) {
if (result.hasData) {
List<MovieModel> popularInnerList = result.data![0];
List<MovieModel> comingInnerList = result.data![1];
List<MovieModel> playingInnerList = result.data![2];
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
const Text(
'Popular Movies',
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 20,
),
),
SizedBox(height: 300, child: makeList(popularInnerList)),
const Text(
'Now in Cinemas',
style:
TextStyle(fontWeight: FontWeight.w900, fontSize: 20),
),
// Expanded(child: playingList(playingInnerList)),
SizedBox(height: 250, child: playingList(playingInnerList)),
const Text(
'Coming Soon',
style:
TextStyle(fontWeight: FontWeight.w900, fontSize: 20),
),
SizedBox(
height: 300,
child: comingList(comingInnerList),
),
],
),
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
)
간략하게 코드 설명을 하자면 위에 정의된 변수에 데이터가 담기면, 세 변수에서의 데이터가 각각 하나의 변수에 담겨 값이 있다면 해당 배열에서 값, 값이 없으면 로딩 중이라는 표시가 뜬다.
현재 코드는 로딩과 데이터를 받아왔을 때 두 상황만 적혀있지만 error발생시(result.hasError)에도 에러메세지를 출력해볼 수 있다
요렇게 !
따로 로딩화면을 만들지 않아도 이용할 수 있는 위젯이 있다니 !!
너무 신기하고 편한 것 같다 ㅎㅎ
참고
https://www.youtube.com/watch?v=zEdw_1B7JHY
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
'junior developer :) > Flutter & Dart' 카테고리의 다른 글
[flutter] getx 라우팅 관리 & argument 값 넘겨주기 (4) | 2023.06.26 |
---|---|
[flutter]Cloud firestore (firebase 이용해서 CRUD 해보기) (4) | 2023.06.23 |
[flutter] flutter 소셜 로그인(1. google + firebase) (4) | 2023.06.20 |
[flutter]logger 적용하기 (print 대신 logger로 더 편리하게 console 이용하기) (4) | 2023.06.19 |
[flutter] Expanded / singleChildScrollView (with.constraintsError) (4) | 2023.06.15 |