🐳Flutter

[Flutter] 사진 다운로드 기능 넣어주세요.. 근데 카카오톡 처럼..!

DevJiun 2022. 1. 6. 19:46

여러장의 사진을 카카오톡 처럼 캐러셀로 만든 후

한번에 다운받거나 현재 페이지의 사진만 저장할 수 있는 기능을 만들어 보도록 합시다.

 

필요한 패키지

 

 

위 패키지들을 현재 플러터 버전에 맞게 설치해 줍니다.

 

저희가 사용할 방법은

PageVIew위젯과 List위젯을 활용할 예정입니다.

 

먼저 코드를 보여드리겠습니다.

 

이미지 리스트를 PageView위젯으로 보여줄 수 있도록 만들어야 합니다.

 

List<Widget> imageList = [];
List<String> images = [
  "https://images.unsplash.com/photo-1533038590840-1cde6e668a91?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80",
  "https://images.unsplash.com/photo-1519770340285-c801df5ff3db?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=983&q=80",
  "https://images.unsplash.com/photo-1492321936769-b49830bc1d1e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80",
  "https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80"
];

for (String image in images) {
      imageList.add(Image.network(image));
}

더미리스트들을 생성한 후 for를 활용해서 PageView에 들어갈 위젯을 만들어 줍시다.

 

그 후 생성된 imageList를 PageView위젯 안에 그대로 넣어주면..

 

 PageView(
   controller: pageController,
   children: imageList,
 ),

 

이러한 화면이 만들어집니다.

 

PageView로 만들었기 때문에 스와이프는 자연스럽게 가능해집니다.

 

이제 하단 버튼에 사진 저장 기능을 만들어야 합니다.

 

먼저 ImageGallerySaver패키지를 활용해 이미지를 저장하는 메서드를 만들어줍시다.

 

void downloadImage(String url) async {
    var status = await Permission.storage.status;

    http.Response response = await http.get(
      Uri.parse(url),
    );

    if (status.isDenied) {
      await Permission.storage.request();
    } else {
      try {
        await ImageGallerySaver.saveImage(
          Uint8List.fromList(response.bodyBytes),
          quality: 100,
          name: (DateTime.now().millisecondsSinceEpoch.toString()),
        );

        print("저장 성공!!");
      } catch (e) {
        print("저장 실패 ㅠㅠ");
      }
    }
  }

 

http 패키지를 활용하면 url를 손쉽게 binary로 변경할 수 있습니다.

권한이 허용되어있지 않다면 권한 허용을 요청하는 팝업을 띄우고 

허용이 되어있다면 이미지를 저장해줍니다.

 

유저 권한도 필요하기 때문에 permision_handler 라이브러리를 활용해야 합니다. 

권한 설정은 해당 라이브러리를 참고해주세요...!!!

 

 InkWell(
                      onTap: () {
                        int currentPageIndex = pageController.page!.toInt();
                        downloadImage(images[currentPageIndex]);
                      },
                      child: Container(
                        width: 120,
                        height: 50,
                        color: Colors.green,
                        child: Center(
                          child: Text("이 사진만 저장",
                              textAlign: TextAlign.center,
                              style: TextStyle(color: Colors.white)),
                        ),
                      ),
                    ),
                    Spacer(),
                    InkWell(
                      onTap: () {
                        for (int i = 0; i < images.length; ++i) {
                          downloadImage(images[i]);
                        }
                      },
                      child: Container(
                        width: 120,
                        height: 50,
                        color: Colors.green,
                        child: Center(
                          child: Text("모든 사진 저장",
                              textAlign: TextAlign.center,
                              style: TextStyle(color: Colors.white)),
                        ),
                      ),
                    ),

버튼 클릭부분 코드입니다.

pagingController는 현재 페이지 인덱스를 가져올 수 있기 때문에

하나의 이미지를 다운받을땐 현재 페이지 인덱스를 넣어서 다운로드 메서드를 한번만 실행하고

전부 받을 경우엔 for 를 활용해서 모든 이미지를 받는 방법입니다.

 

전체 코드는 아래 깃허브 링크에서 확인해주세요. 

https://github.com/jiun-dev/flutter-image-save