수강 강의: https://url.kr/inflearn
진도: 104강 / 178강
Data: NULL
Connection State: None
Data: NULL
Connection Sate: Connection State.waiting
Data: (값)
Connection State: Connection State.done
Connection State가 바뀔 때 마다 빌더 함수가 새로 불리기 떄문에 SetState를 실행하지 않아도 화면이 바뀌는 것을 알 수 있다.
그럼 Connection State가 Done이 된 상태로 SetState함수를 실행하면 어떻게 될까?
SetState를 하면 Build가 다시 불리기 때문에 당연히, Future Builder가 다시 실행된다.
Future Builder가 다시 실행되는 동안, Connection State는 waiting이 되고, Data는 null이 되지 않고 그전 데이터가 그대로 유지된다.
그리고나서 Connection State가 Done이 되면 Data에 새로운 Future값이 들어온다.
이를 캐싱이라고 한다.
캐싱 : FutureBuilder가 기존의 데이터 값을 기억하는 것을 말함
이를 어디에 사용할 수 있을까?
Facebook같은 앱에서, 새로운 항목을 로딩 할 때 화면 전체가 로딩되지 않고 일부에만 로딩화면이 보이고 로딩이 완료된다. 이것은 기존 데이터를 유지하는 캐싱을 이용한 것이다.
if(snapshot.connectionState == ConnectionState.waiting) CicularProgressIndicator
와 같이 if문을 사용해서 로딩해야 하는 항목에만 적용해주는 것이 더 효율적이다. 이렇게 하지 않고 앱 전체가 로딩되게 하면 앱이 굉장히 느려보이기도 한다.
에러는 throw로 받아오면 된다.
throw Exception('에러가 발생했습니다.')
로 작성할 경우, Error: Excetion: 에러가 발생했습니다. 로 화면에 잘 나온다.
Error도 캐싱이 될까?
throw를 주석처리하고 다시 SetState 하면 waiting이 되는 동안 Error는 그대로이다. SetState가 Done이 되어야 Error:None으로 나온다. 따라서 Error도 캐싱이 된다.
snapshot.hasData : snapshot 값이 있으면 Ture, 없으면 False를 반환한다
Stream<int> streamNumbers() async* {
for (int i = 0; i < 10; i ++){
await Future.delayed(Duration(seconds: 1))
yield i;
}
위와 같은 코드로 Stream을 만들어줬다.
Data가 ConnectionState.active 에서 시작해서, 1초마다 0~9까지 올라가는 코드이다.
9까지 올라가면 ConnectionState.done 상태가 된다.
StreamBuilder도 FutureBuilder와 마찬가지로 캐싱이 된다.
StreamBuilder의 경우에는 모든 Build를 닫는 것까지 작업을 해주기 때문에 우리가 신경 쓸 필요가 없다는 장점이 있다.

Permission Handler
https://pub.dev/packages/permission_handler

mainAxisSize: MainAxisSize.min
사이즈를 최소한의 값만 차지하도록 하려면 MainAxisSize.min을 사용하면 된다.
여기서 조금 더 키우고 싶으면 padding값을 이용해서 키울 수 있다.
Column으로 감싸주고 mainAxisAlignment: MainAxisAlignment.end 로 설정해주면 가장 아래로 위치하게 된다.
letterSpacing : (값) 값이 커질수록 자간이 커진다
borderRadius: BorderRadius.circular(값)
테두리 둥글게 값이 커질수록 둥굴어짐
BoxSadow
BoxShadow: (
color: Colors.blue[300]!,
blurRadius: 12.0 // 퍼지는 영역
spreadRadius: 2.0, // 그림자 영역
)
Align( alignment: Alignment.topLeft, child: Text('Hi'))
Align 함수를 이용해서 원하는 위치에 정렬 할 수 있다.
Future<bool> init() async {
final resp = await [Permission.camera, Permission.microphone].requewst(); // 권한을 받아온다
final cameraPermission = resp[Permission.camera]; // 카메라 권한 값을 cameraPermission에 저장
final microphonePermission = resp[Permission.microphone]; // 마이크 권한 값을 microphonePermission에 저장
if(cameraPermission != PermissionStatus.granted || microphonePermission != PermissionStatus.granted){
throw '카메라 또는 마이크 권한이 없습니다.';
}
return true;
}
PermissionStatus.granted 는 권한이 있는 것을 뜻한다.
따라서, if문은 '@에 대한권한이 없다면~' 을 말한다.
이벤트 핸들러로 4가지 경우를 제어할 수 있다.
나의 uid 저장
나의 uid null
상대의 uid 저장
상대의 uid null
=> API만 사용하면 돼서 생각보다는 쉬웠다

실제로 이 서비스를 출시했을 때, 어떤 식으로 서비스를 구현하게 될까?
가장 문제는 토큰이 24시간만 유용하다는 것이다.
따라서 서버를 만들어야 한다.
서버와 아고라 API를 연결해야한다.
그렇게 해서 A와 B라는 사람이 영상통화를 할 때 토큰을 받아올 수 있어야 한다.
구매할 것인가 직접 만들것인가?
어떤 걸 만들고 어떤 API를 구매해서 써야 할까?
좋은 이야기인 것 같아서 캡쳐해왔다


지금 봤을 때는 Buy로 초기 개발을 하고 나중에 Build로 하는게 좋을 것 같은데.. 이미 Buy한 걸로 만든 서비스를 Build한 걸로 대체하는게 쉽지 않을 것 같긴 함
defaultDecoration, weekendDecoration, selectedDecoration 모두 따로 지정해주어야 한다.
따라서 BoxDecoration을 따로 위젯으로 만든 뒤에 넣어주는 것이 좋다.
TextStyle도 마찬가지로 defaultTextStyle, weekendTextStyle, selectedTextStyle 모두 따로 지정해주어야 하므로 TextStyle 위젯을 따로 만든 뒤에 넣어주는 것이 좋다.
1월에 Focus가 된 상태로 2월 날짜를 누르면 에러가 난다.
첫 번째는 눌렀을 때 빨간색 에러 화면이 보이는 것이고, 두 번째는 날짜 Focus가 이동되지 않는 것이다.
defaulDecoration은 BorderRadius를 주었는데, outsideDecoration은 Circle 형태로 BorderRadius가 불가능해서 에러가 난다. 따라서 outsideDecoration도 따로 설정해준다.
outsideDecoration: defaultBoxDeco
1월 => 2월로 날짜를 선택했을 때 focuseDay도 같이 이동하도록 해주면 된다.
setState(() {
this.selectedDay = selectedDay;
this.focuseDay = selectedDay;
},
Intl 패키지를 이용해서 언어를 변경한다.
현재까지 강의를 들으며 진행한 사항은 아래와 같다.
