앱을 처음 실행했을 경우 로딩화면이 나오고 메인화면을 실행하도록 하는 방법을 알아보자
몇가지 방법이 있겠지만 구현한 2가지 방법을 소개한다.

void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class PostHomePage extends ConsumerWidget {
const PostHomePage({Key? key}) : super(key: key);
Widget build(BuildContext context, WidgetRef ref) {
PostController pc = ref.read(postController);
return Scaffold(
body: Column(
children: [
Expanded(
// FutureBuilder
child: FutureBuilder(
future: pc.findPosts(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return _buildMainScreen( // 화면 그리기
snapshot.data);
} else {
return _buildErrorScreen(); // 실패한다면
}
} else {
return _buildLoadingScreen(); // 로딩중 화면
}
},
),
),
// buildButton(pc),
],
),
);
}
future 속성에는 Future<>를 리턴하는 메소드를 넣는다.
비동기처리를 하므로 완료가 되면 future 다음 라인부터 다시 실행된다.
AsyncSnapshot은 FutureBuilder나 StreamBuilder와 함께 사용되는 클래스로, 비동기 작업의 결과를 포함하고 이에 대한 상태 정보를 제공한다.
snapshot.data를 통해 비동기 작업의 결과를 제공하고
snapshot.connectionState를 통해 현재 상태 정보를 제공한다.
none: 아직 비동기 작업이 수행되지 않은 상태
waiting: 비동기 작업이 실행 중이며 결과를 기다리고 있는 상태
active: 스트림에서 이벤트가 발생하고 있는 상태
done: 비동기 작업이 완료되었으며, snapshot.data에서 결과가 사용 가능한 상태
Widget _buildMainScreen(List<Post> posts) {
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
return Column(
children: [
Container(
decoration: BoxDecoration(color: Colors.green[100]),
height: 100,
child: ListTile(
leading: Text("${posts[index].id}"),
title: Text("${posts[index].title}"),
),
),
Divider(),
],
);
},
);
}
Widget _buildErrorScreen() {
return Container(
child: Center(
child: Text("실패"),
),
);
}
Widget _buildLoadingScreen() {
return Container(
child: Center(child: CircularProgressIndicator())
);
}
}
ProviderScope 지정은 위와 같다.
변화가 필요한 부분만 Consumer로 감싼다.
builder속성을 가지면 메소드를 호출할 수 있다.
class PostHomePage extends StatelessWidget {
const PostHomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: Consumer(
builder: (context, ref, child) {
PostController pc = ref.read(postController);
pc.findPosts();
PostHomePageModel? pm = ref.watch(postHomePageProvider);
return pm != null
? buildListView(pm.posts)
: Center(child: CircularProgressIndicator());
},
),
),
],
),
);
}
Widget buildListView(List<Post> posts) {
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
return Column(
children: [
Container(
decoration: BoxDecoration(color: Colors.green[100]),
height: 100,
child: ListTile(
leading: Text("${posts[index].id}"),
title: Text("${posts[index].title}"),
),
),
Divider(),
],
);
},
);
}
}