가을기 Workspace

[플러터] 25일차 - 이미지 파일 내려받기 본문

개발/개인앱

[플러터] 25일차 - 이미지 파일 내려받기

가을기_ 2021. 8. 12. 23:18

앱을 사용하다 보면 용량이 큰 파일을 내려받아야 할 때가 있다.

유저는 파일을 내려받을떄 까지 기다려야하는데, 화면에 아무런 정보가 표시되지 않는다면 앱이 멈춘것으로 생각할 수 있다. 파일을 내려받을 때 진행 상황을 표시해줄 필요가 있다.

환경 준비

  • dio: 파일을 내려받는 패키지
  • path_provider: 내부 저장소 패키지
dependencies:
  flutter:
    sdk: flutter

  dio: ^4.0.0
  path_provider: ^2.0.2

 

화면

 

코드


import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'


void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LargeFileMain(),
    );
  }
}


class LargeFileMain extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _LargeFileMainState();
}

class _LargeFileMainState extends State<LargeFileMain> {
  bool downloading = false;
  var progressString = "";
  var file = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Large File Example'),
      ),
      body: Center(
        child: downloading ? Container(
          height: 120.0,
          width: 200.0,
          child: Card(
            color: Colors.black,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CircularProgressIndicator(),
                SizedBox(
                  height: 20.0,
                ),
                Text(
                  'Downloading File: $progressString',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                )
              ],
            ),
          )
        ) : FutureBuilder(
          future: downloadWidget(file),
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                print('none');
                return Text('데이터 없음');
              case ConnectionState.waiting:
                print('waiting');
                return CircularProgressIndicator();
              case ConnectionState.active:
                print('active');
                return CircularProgressIndicator();
              case ConnectionState.done:
                print('done');
                if (snapshot.hasData) {
                  return snapshot.data as Widget;
                }
            }

            print('end process');
            return Text('데이터 없음');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          downloadFile();
        },
        child: Icon(Icons.file_download),
      ),
    );
  }

  Future<Widget> downloadWidget(String filePath) async {
    File file = File(filePath);
    bool exist = await file.exists();
    new FileImage(file).evict();

    if (exist) {
      return Center(
        child: Column(
          children: [
            Image.file(File(filePath)),
          ],
        ),
      );
    } else {
      return Text('No Data');
    }
  }

  Future<void> downloadFile() async {
    var dio = Dio();

    print('Download started');
    try {
      var dir = await getTemporaryDirectory();

      var response = await dio.download(
          'https://images.pexels.com/photos/240040/pexels-photo-240040.jpeg?auth=compress',
          '${dir.path}/myimage.jpg',
          // './example/flutter.png',
          onReceiveProgress: (rec, total) {
            print('Rec: $rec, Total: $total');
            file = '${dir.path}/myimage.jpg';
            setState(() {
              downloading = true;
              progressString = ((rec / total) * 100).toStringAsFixed(0) + '%';
            });
          },
        options: Options(sendTimeout: 30000, receiveTimeout: 30000),
      );
      print(response);
    } catch (e) {
      print(e);
    }

    setState(() {
      downloading = false;
      progressString = 'Completed';
    });

    print('Download completed');
  }
}

 

인터넷 환경에 주의!

참고: 22일차 - 카카오 api 활용하기

 

Comments