TIL - 지역 검색 앱 (3) <AlertDialog의 context, 파이어스토리지에 에셋이미지 업로드하기>
## 해당 TIL은 주어진 과제를 수행하면서 얻은 학습 내용과, 시행착오 등등을 종합해서 작성한것임
1. AlertDialog 상태변경이 안되던 문제
현재 프로젝트에서 AlertDialog를 사용할때,
아래와 같은 형태로, 위젯을 만들어 사용하고 있었다.
Widget addChat(BuildContext context) {
return IconButton(
onPressed: () => showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => plusChatRoomDialog(context),
),
icon: Icon(
Icons.add_box_outlined,
color: Colors.grey,
size: 32,
));
}
Widget plusChatRoomDialog(BuildContext context) {
return AlertDialog(..);
}
발생한 문제는, AlertDialog에서 상태를 변경하고, UI를 업데이트하려는데 UI업데이트 로직이 제대로 작동하지 않는 문제였다.
구글링 결과
빌더에서 반환된 위젯은 showDialog가 원래 호출된 위치와 컨텍스트를 공유하지 않습니다.
대화 상자를 동적으로 업데이트해야 하는 경우 StatefulBuilder 또는 사용자 지정 StatefulWidget을 사용하세요 .
즉, AlertDialog는 BuildContext를 공유하지 않는 별개의 context로 다뤄지기 때문에, UI 업데이트 로직을 수행할때, 따로 해주어야 한다는 의미였다.
위의 방식처럼 그냥 Widget 형태로 AlertDialog를 사용한후 그냥 setState를 사용하게 되면, AlertDialog가 업데이트되는게 아닌, 상위 위젯인 StatefulWidget이 업데이트 된다는 소리이다.
따라서 AlertDialog만 업데이트하려면, AlertDailog를 따로 떼어네어 StatefulWidget으로 만들거나,
해당 위젯을 StatefulBuilder로 감싸주는 방식이 필요하다.
또한, 외부의 변수들을 사용하지 않아야 제대로 작동하기 때문에, 새로 만들어진 Widget 내부에서 변수를 추가하여 빌더 내부에서 변수를 변경하는 식으로 해야 제대로 작동하게 된다!
Widget plusChatRoomDialog(BuildContext context) {
final detailState = ref.watch(detailViewModelProvier);
return StatefulBuilder(builder: (BuildContext context, setState) {
return GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: AlertDialog(..),
< 참고 >
How to refresh an AlertDialog in Flutter?
Currently, I have an AlertDialog with an IconButton. The user can click on the IconButton, I have two colors for each click. The problem is that I need to close the AlertDialog and reopen to see the
stackoverflow.com
[flutter] dialog State refresh하기
State 딱대
velog.io
2. 파이어 스토리지 에셋 이미지 업로드 방법
파이어 스토리지를 이용해 이미지를 업로드 하는 방법은 다음과 같다.
해당 방식은, 로컬 이미지를 파이어 스토리지에 업로드 하는 방법이다.
FirebaseStorage storage = FirebaseStorage.instance;
Reference storageRef = storage.ref();
// 업로드 로직
await storageRef.child('파일명').putFile(File(xFile.path')));
그런데, 만약 에셋 파일의 에셋 이미지를 파이어 스토리지에 업로드 하고 싶은 경우는 어떻게 해야 할까?
에셋 파일을 업로드 하기 위해서는, 에셋 파일을 디렉토리에 임시 저장한후, 파일 형태로 재 변환시켜 업로드 시켜주어야 하는 방식을 사용해야 했다.
String _image = "assets/images/default_img.jpg";
String _imageName = "임시파일명";
Directory systemTempDir = Directory.systemTemp;
ByteData byteData = await rootBundle.load(_image);
File file = File("${systemTempDir.path}/$_imageName.jpeg");
await file.writeAsBytes(byteData.buffer.asUint8List(
byteData.offsetInBytes, byteData.lengthInBytes));
// 업로드 로직
FirebaseStorage.instance.ref("test/$_imageName").putFile(file);
또한, HTTP 통신을 통해 받아온 이미지를 업로드하는 방법,
NetworkImage를 업로드 하는 방법등등 이 있는데 이는, 밑의 링크를 참고바란다..
[Flutter] Firebase Storage 사용해 보기
Firebase Storage 사용해 보기 Firebase Cloud Storage Documentation firebase_core | Flutter Package firebase_storage | Flutter Package http | Dart Package
velog.io