日常开发中,经常会遇到下载文件的功能,往往我们在需要保存文件的路径上去调试,比如Android中的路径,有些会报错在SD卡中,但是有些手机,又没有SD卡,那么我们该怎么办呢?
为了功能的完善,往往需要一个下载的进度条,当然,UI怎么美化不管,核心代码如下:
Container(
padding: EdgeInsets.symmetric(horizontal: 32.w),
height: Get.height,
alignment: Alignment.center,
child: Obx(
() => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(4.r),
),
color: Colors.white,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 22.h, bottom: 4.h),
child: Text(
'发送文件',
style: TextStyles.normalTextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w500,
),
),
),
Container(
width: Get.width,
padding:
EdgeInsets.only(right: 24.w, left: 24.w, bottom: 12.h),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: 8.h,
bottom: 12.h,
),
child: Text(
controller.scheduleLoad.value != '100'
? '文件正在下载中,请稍候'
: '文件已下载完成',
style: TextStyles.normalTextStyle(
fontSize: 14.sp,
color: Colours.textGrey9,
),
),
),
InkWell(
onTap: controller.scheduleLoad.value == '100'
? () {
shareDialog(title);
}
: null,
child: Container(
height: 74.h,
alignment: Alignment.center,
child: SizedBox(
height: 40.h,
child: Stack(
children: [
ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(20.r)),
child: SizedBox(
height: 40.h,
child: LinearProgressIndicator(
value: double.tryParse(
controller.scheduleLoad.value),
backgroundColor: Colours.blueBtnBg02,
valueColor: const AlwaysStoppedAnimation(
Colors.blue,
),
),
),
),
Center(
child: Text(
controller.scheduleLoad.value != '100'
? "下载进度${controller.scheduleLoad.value}%"
: '分享文件',
textAlign: TextAlign.center,
style: TextStyles.normalTextStyle(
color: Colors.white,
fontSize: 14.sp,
),
),
),
],
),
),
),
),
],
),
),
],
),
),
),
)
上面的代码中,定义了一个视图,用来展示下载进度的信息,这里我使用的是getx 的状态管理,直接使用Obx进行下载数据的实时监听刷新。
首先我们需要传入一个文件的下载路径,然后使用三方插件path_provider来获取文件的路径。
if (filePath != null) {
String? docPath;
if (Platform.isAndroid) {
docPath = "/storage/emulated/0/Download/";
Directory dir = Directory(docPath);
try {
dir.listSync();
}catch (e){
// 一些系统没有权限
docPath = (await getExternalStorageDirectory())?.path;
docPath = '$docPath/';
}
} else {
docPath = (await getTemporaryDirectory()).path;
docPath = docPath.replaceFirst("Library/Caches", "Documents/");
}
loadFilePath = '$docPath$name.docx';
}
上面的代码中,docPath 定义的一个路径,字面意思就是模拟器中的外部下载文件路径,但是在有些手机中,没有外部SD卡,那么我们再获取一下当前设备的内部SD卡路径, (await getTemporaryDirectory()).path, 其实getTemporaryDirectory 字面意思也是获取的外部存储路径,但是在没有外部SD卡的时候,他会获取内部的存储路径。
文件上传部分,直接使用Dio 中封装好的方法就行
await Dio()
.download(filePath, loadFilePath, onReceiveProgress: (int received, int total) {
if (total != -1) {
scheduleLoad.value = (received / total * 100).toStringAsFixed(0);
}
});
到此为止,整个文件的下载保存功能就做完了,可以直接在手机的下载文件目录中查看下载的文件