들어가며..
앞서 본 블로그에서 Jsonplaceholder에서 제공하는 API를 http
패키지를 사용하여 연동하였다.
Flutter는 앞서 살펴본 API응답객체인 Future
에 대한 대응 Widget으로, FutureBuilder
를 제공한다.
이번 장에서는 FutureBuilder
사용법에 대해 간단히 살펴보고자 한다. 앞서 진행한 소스는 첨부하지 않으므로 아래 관련 포스트에서 먼저 확인하길 바란다.
관련 포스트
2022.03.17 - [Flutter] - Flutter(Dart) - Model 객체 Json 매핑 쉽게 하기(@JsonSerializable)
2022.03.18 - [Flutter] - Flutter(Dart) - http 패키지 사용법 및 유닛테스트
FutureBuilder
Future
객체는 비동기처리 결과를 처리하는 객체로서, snapshot
정보를 통해 비동기 처리 결과를 얻을 수 있다.
FutureBuilder 생성자 구조
const FutureBuilder({
Key? key,
this.future,
this.initialData,
required this.builder,
}) : assert(builder != null),
super(key: key);
builder
는AsyncWidgetBuilder<T>
클래스로서,AsyncSnapshot
객체를 제공한다. 이 스냅샷은Future
객체에 대한 처리 과정, 결과를 제공한다. ( 스냅샷으로부터connectionState
, 데이터 존재 유무를 확인 할 수 있다. 이는 아래에서 살펴본다. )future
에FutureBuilder
가 처리할Future
객체를 바인딩한다. 여기서는 List post 객체를 얻어오는 함수를 바인딩한다.
📃 lib/view/homepage.dart
class HomePage extends StatefulWidget {
const HomePage({Key? key, required this.fakePostApi}) : super(key: key);
final FakePostApi fakePostApi;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late Future<List<Post>> _allPosts;
@override
void initState() {
super.initState();
_allPosts = widget.fakePostApi.fetchAllPosts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('FutureBuilder'),
centerTitle: true,
),
body: _FetchAllPosts(context),
);
}
- HomePage는 생성자 파라미터로 API매니저 객체를 받는다.
FakePostApi
에 모든 포스트정보를 조회하는fetchAllPosts
함수를initState
에서 호출한다.
❗ Widget의 build 함수는 이벤트 트리거등에 의해 수시로 rebuilding되므로 일회성 호출 함수가 존재해서는 안된다.
_FetchAllPosts
Widget _FetchAllPosts(context) {
return FutureBuilder(
future: _allPosts,
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// 요청으로 부터 아직 응답이 없는 경우
} else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
// 에러가 발생한 경우
} else { // hasData
// 정상적으로 데이터를 수신한 경우
}
} else {
// Future 객체가 null 인 경우
}
}));
}
future
에 위 initState에서 호출하여 얻는Future
객체를 바인딩한다.snapshot
은 위와 같이 3개의 상태를 갖는다.snapshot.hasData
에서 정상적으로 얻어온 포스트 리스트 데이터를 출력한다.
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
} else { // hasData
List<Post> _posts = snapshot.data as List<Post>;
return ListView.separated(
itemCount: _posts.length,
itemBuilder: ((context, index) {
Post _post = _posts[index];
return ListTile(
title: Text(
_post.title,
maxLines: 1,
),
contentPadding: const EdgeInsets.fromLTRB(15, 5, 15, 0),
subtitle: Text(_post.body, maxLines: 2),
);
}),
separatorBuilder: (context, index) => const Divider(
thickness: 0.3,
));
}
} else {
return const Center(
child: Text('No data found'),
);
}
Result
반응형
'Mobile Programming' 카테고리의 다른 글
문제해결: Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found while decoding string: (0) | 2022.05.30 |
---|---|
Flutter - 간단한 초 타이머 만들기 (With StreamSubscription) (0) | 2022.05.06 |
Flutter(Dart) - http 패키지 사용법 및 유닛테스트 (0) | 2022.03.18 |
Flutter(Dart) - Model 객체 Json 매핑 쉽게 하기(@JsonSerializable) (0) | 2022.03.17 |
Flutter - has been blocked by CORS policy, 크롬 실행 시 발생 오류 해결방법. (0) | 2022.02.21 |