Contents
Provider / vm 구조에서 통신Provider / vm 구조에서 통신
view (그림 그리기)
View Model (상태관리, 비즈니스로직, 파싱)
Repository (통신)
main
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'future_page.dart';
import 'home_page.dart';
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
runApp에 ProviderScope 달아준다.
home_page
import 'package:flutter/material.dart';
import 'home_body.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: HomeBody(),
);
}
}
body에 HomeBody( ) 만들어준다.
home_body 작성 전에 home_page_vm 만들어준다.
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockapp/home_repository.dart';
final homeProvider = NotifierProvider<HomePageVM, int?>(() {
return HomePageVM();
});
class HomePageVM extends Notifier<int?> {
HomeRepository repo = const HomeRepository();
// 상태
@override
int? build() {
// 상태 초기화 시작
getOne(); // 초기화 여기서 vm 빌드에서
// 상태 null 초기화
return null;
}
// 행위
Future<void> getOne() async{
int one = await repo.getOne();
state = one;
}
}
VM은 Repository를 의존한다!!
상태 초기화 시 >> repo의 getOne( ) 실행
getOne 은 비동기 함수로 repo에서 실행시키고 바로 튀어나온다.
home_repository만들기
// SRP : 데이터를 가져오는 곳
// (휴대폰 디바이스(파일), 휴대폰 DB, Firebase(외부서버), 내 서버, 공공데이터서버)
class HomeRepository {
const HomeRepository();
// 반환 타입 Future<실제 받을 반환타입> <-형태 기억하기
Future<List<int>> getList() async {
// 비동기 / response는 promise데이터
List<int> response = await Future.delayed(Duration(seconds: 3), () {
// 3초 후 실행됨..
return [1,2,3,4];
},);
return response;
}
Future<int> getOne() async{
int response = await Future.delayed(Duration(seconds: 3), () {
// 3초 후 실행됨..
return 5;
},);
return response;
}
}
repository에서는 모든 것들이 비동기로 실행되고,
Future<실제 반환 타입> 함수명( ) async { } 형태로 이루어진다.
◎ 실제 반환 타입이 없더라도 Future<void> 함수명( ) async로 기재해야한다.
home_body
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mockapp/home_page_vm.dart';
import 'package:mockapp/home_repository.dart';
class HomeBody extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
int? one = ref.watch(homeProvider);
if(one == null){
return Center(child: CircularProgressIndicator());
}else{
return Column(
children: [
Center(child: Text("$one", style: TextStyle(fontSize: 50))),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (context, index) {
return ListTile(leading: Text("${index + 1}"),title: Text("내용"));
}),
),
],
);
}
}
}
int? one = ref.watch(homeProvider); 코드를 통해 provider가 창고(VM)을 만든다.
이때 창고에 있는 상태는 통신을 통해 가져오는데,
home_page_vm에서

초기 상태는 null 값이 된다.
이 null 값일 때 화면을 처리하기 위해서 if( )else( )를 사용해서 처리를 한다.
int? one = repo.watch(homeProvider); << int? 로 받는 이유
if(one == null){
return Center(child: CircularProgressIndicator());
}else{
return Column(
children: [
Center(child: Text("$one", style: TextStyle(fontSize: 50))),
Expanded(
child: ListView.builder(
itemCount: 4,
itemBuilder: (context, index) {
return ListTile(leading: Text("${index + 1}"),title: Text("내용"));
}),
),
],
);
만약 지켜보고 있는 상태(one)가 null 일 경우
View는 CircularProgressIndicator()화면에 그리게 된다.
통신을 통해 데이터가 들어와 null이 아니라면
else의 Column 그림이 그려지게 된다.
Share article