파일다운로드시 진행상태 표시 예제
pubspec.yaml
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dio: ^4.0.6
path_provider: ^2.0.11
main.dart
import "package:flutter/material.dart";
import "package:largefile_download/LargeFileMain.dart";
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Large file download App",
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const LargeFileMain(title: "This is large file download App!"),
);
}
}
LargeFileMain.dart
import "package:flutter/material.dart";
import "package:dio/dio.dart";
import "package:path_provider/path_provider.dart";
import "dart:io";
class LargeFileMain extends StatefulWidget {
const LargeFileMain({super.key, required this.title});
final String title;
@override
State<StatefulWidget> createState() {
return _LargeFileMain();
}
}
class _LargeFileMain extends State<LargeFileMain> {
TextEditingController? _textEditingController;
bool downloading = false;
var progressString = "";
String file = "";
@override
void initState() {
super.initState();
_textEditingController = TextEditingController(text: "https://images.pexels.com/photos/240040/pexels-photo-240040.jpeg?auto=compress");
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
controller: _textEditingController,
keyboardType: TextInputType.url,
style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(hintText: "url을 입력하세요."),
)
),
body: Center(
child: downloading
? SizedBox(
height: 120.0,
width: 200.0,
child: Card(
color: Colors.black,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const CircularProgressIndicator(),
const SizedBox(
height: 20.0,
),
Text(
"Downloading File: $progressString",
style: const TextStyle(
color: Colors.white,
),
),
],
),
),
)
: FutureBuilder(
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
print("none");
return const Text("데이터 없음");
break;
case ConnectionState.waiting:
print("waiting");
return const CircularProgressIndicator();
break;
case ConnectionState.active:
print("active");
return const CircularProgressIndicator();
break;
case ConnectionState.done:
print("done");
if (snapshot.hasData) {
return snapshot.data as Widget;
}
break;
}
print("end process");
return const Text("There is no data.");
},
future: _downloadWidget(file),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_download();
},
child: const Icon(Icons.file_download),
),
);
}
Future<void> _download() async {
Dio dio = Dio();
try {
Directory dir = await getApplicationDocumentsDirectory();
await dio.download(_textEditingController!.value.text, "${dir.path}/myimage.jpg",
onReceiveProgress: (rec, total) {
//print("Rec: $rec, Total: $total");
file = "${dir.path}/myimage.jpg";
//print(dir.path);
setState(() {
downloading = true;
progressString = "${((rec / total) * 100).toStringAsFixed(0)}%";
});
}
);
} catch (e) {
print(e);
}
setState(() {
downloading = false;
progressString = "Completed!";
});
print("Download completed!");
}
Future<Widget> _downloadWidget(String filePath) async {
File file = File(filePath);
bool exist = await file.exists();
FileImage(file).evict();
if (exist) {
return Center(
child: Column(
children: <Widget>[
Image.file(File(filePath)),
],
),
);
}
else {
return const Text("There is no data");
}
}
}