: 데이터를 다 받기전, 데이터가 없이 그릴 수 없는 부분을 먼저 그려주기 위해 사용됨.
비동기상황에서 뷰대응을 해주기 위해 사용되는 클래스
(future을 사용하는 이유와 비슷. future는 작업이 완료되면 결과를 받는 방식으로 비동기 처리를 하니까)
만약 futureBuilder가 없다면 데이터가 다 받아지기를 기다린 후 화면을 그리거나 setState()를 통해 바꿔주어야 한다.
예제) 화면 로딩되는 동안 indicator가 보여지는 예제
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'이곳은 데이터 상관없이 불려져 오는 곳입니다',
style:TextStyle(fontSize: 20),
),
FutureBuilder(
future: _fetch1(),
builder: (BuildContext context, AsyncSnapshot snapshot){
//data를 아직 받지 못했을 때 실행되는 부분
if(snapshot.hasData == false){
return CircularProgressIndicator();
}
//error 발생될 경우
else if (snapshot.hasError){
return Padding(
padding: const EdgeInsets.all(8),
child: Text(
'Error: ${snapshot.error}',
style: TextStyle(fontSize: 15)
)
);
}
//데이터를 정상적으로 가져온 경우
else {
return Padding(
padding: const EdgeInsets.all(8),
child: Text(
snapshot.data,
style: TextStyle(fontSize: 15),
)
);
}
}
)
],
),
),
);
}
Future<String> _fetch1() async{
await Future.delayed(Duration(seconds: 5));
return 'Call Data';
}
}
초기화면
5초뒤 화면
futurebuilder를 구성하는 세 가지 child, future, builder
future
: Future< T>를 return 하는 메소드를 넣음
builder
: context와 snapshot을 인수로 갖고 위젯을 리턴하는 메소드를 넣음.
(snapshot은 Future< T>의 return 값을 의미함)
future값에 따라 원하는대로 위젯을 build하도록 설정하면 값이 바뀔 때 다시 build가 된다
futurebuilder은 설정한 future 상태가 바뀔 때마다 builder부분이 다시 실행됨