앱을 처음 실행했을 경우 로딩화면이 나오고 메인화면을 실행하도록 하는 방법을 알아보자
몇가지 방법이 있겠지만 구현한 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(),
],
);
},
);
}
}