gpt의 도움 받고 약 3시간 30분 정도 걸렸다.
자꾸 레이아웃 에러가 나서 같은 모양에서 조금씩 바꾸기만 3시간 한 듯.
처음 레이아웃을 잘 잡는게 중요한 것 같다.
사용한 라이브러리는 getx와 file_picker이고
오래 걸렸던 이유는 ListView.builder를 사용해 뷰를 그릴때는 부모위젯을 Expanded로 감싸주어야한다는 사실을 몰랐기 때문이다.
이런 모양을 만들때 사진을 추가하는 쪽 로직.
아래는 코드
-view-
Row(
children: [
AddPhoto(
onPressed: controller.onFileSelected,
),
const SizedBox(width: 16),
Obx(() => controller.selectedFile.isNotEmpty
? Expanded(
child: SizedBox(
height: 80,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: controller.selectedFile.length,
itemBuilder: (context, i) {
final imageBytes = controller.selectedFile[i].bytes;
return Padding(
padding:
const EdgeInsets.symmetric(horizontal: 4.0),
child: Stack(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
border: Border.all(
width: 1, color: grayLight),
color: Colors.white,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Image.memory(
imageBytes!,
fit: BoxFit.cover,
errorBuilder:
(context, error, stackTrace) {
return Container(
color: grayLight,
alignment: Alignment.center,
child: const Text('not found'),
);
},
)),
),
Positioned(
top: 4,
right: 4,
child: GestureDetector(
onTap: () {
controller.removeFile(i);
},
child: Container(
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: const Icon(
Icons.close,
color: Colors.white,
size: 16,
),
),
),
)
],
),
);
},
),
),
)
: const SizedBox(width: 80, height: 80)),
],
)
-controller-
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class ContactPostDetailController extends GetxController {
RxList<PlatformFile> selectedFile = RxList<PlatformFile>([]);
@override
void onInit() {
selectedFile.clear();
super.onInit();
}
void onFileSelected() async {
if (selectedFile.length >= 10) {
ToastWidget('이미지는 10개까지만 첨부가 가능합니다.').green();
return;
}
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
selectedFile.add(result.files.first);
} else {
ToastWidget('파일 선택이 취소되었습니다.').green();
return;
}
}
void removeFile(int index) {
selectedFile.removeAt(index);
}
}
이렇게 완성.
삭제도 잘된다.
기억할 점
- ListView.builder를 사용해 뷰를 그릴때는 부모위젯을 Expanded로 감싸주어야한다
(+)
Assertion failed: org-dartlang-sdk:///lib/_engine/engine/window.dart:91:12
!isDisposed
"Trying to render a disposed EngineFlutterView."
자꾸 이런 비동기 에러가 뜨던데
StatelessWidget에서 StatefulWidget으로 변경해주면 안뜬다.