[flutter] 이미지 파일 여러 장 올리기 (1)

namYeJi9q·2024년 5월 27일
0

Flutter

목록 보기
7/8
post-thumbnail

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으로 변경해주면 안뜬다.

profile
개발로 먹고 살 예정

0개의 댓글