Flutter 实现文件下载

01

Flutter 中的进度指示器

Material 库中进度指示器有两个 :

  • LinearProgressIndicator : 线性进度条指示器

  • CircularProgressIndicator : 圆环进度条指示器

这两个指示器都有精准精度和模糊精度两种模式。

 

1、LinearProgressIndicator

定义如下 :

LinearProgressIndicator({
  double value,
  Color backgroundColor,
  Animation<Color> valueColor,
  ...
})
  • value : 当前进度value : 当前进度

  • backgroundColor : 指示器背景色

  • valueColor : 指示器进度条颜色

使用:

//线性进度条进度动画
  Padding(
    padding: EdgeInsets.all(16),
    child: LinearProgressIndicator(
      backgroundColor: Colors.grey[200],
      valueColor: ColorTween(begin: Colors.grey, end: Colors.red)
          .animate(_controller),
      value: _controller.value,
    ),
  ),



  //线性进度条模糊动画
  Padding(
    padding: EdgeInsets.all(16),
    child: LinearProgressIndicator(
      backgroundColor: Colors.grey[200],
      valueColor: AlwaysStoppedAnimation(Colors.blue),
    ),
  ),

 

2、CircularProgressIndicator

CircularProgressIndicator 和 LinearProgressIndicator 的定义和使用都类似。

使用:

Padding(
    padding: EdgeInsets.all(16),
    child:
    // 模糊进度条(会执行一个旋转动画)
    CircularProgressIndicator(
      backgroundColor: Colors.grey[200],
      valueColor: AlwaysStoppedAnimation(Colors.blue),
    ),
  ),


  //精准进度
  Padding(
    padding: EdgeInsets.all(10),
    child:
    SizedBox(
      width: 150,
      height: 150,
      child:
      CircularProgressIndicator(
        backgroundColor: Colors.grey[200],
        valueColor: ColorTween(begin: Colors.grey, end: Colors.red)
            .animate(_controller),
        value: _controller.value,

      ),
    ),

  ),

 

效果:

 

02

Dio 的使用

下载文件使用了 dio 这个库, 这里简单介绍,详细的使用参考官网文档。

1、基础使用

最简单的示例:

import 'package:dio/dio.dart';
void getHttp() async {
  try {
    Response response = await Dio().get("http://www.baidu.com");
    print(response);
  } catch (e) {
    print(e);
  }
}

 

2、使用 dio 下载文件

dio 中的下载文件方法声明如下:

  Future<Response> download(
    String urlPath,
    savePath, {
    ProgressCallback onReceiveProgress,
    Map<String, dynamic> queryParameters,
    CancelToken cancelToken,
    bool deleteOnError = true,
    lengthHeader = HttpHeaders.contentLengthHeader,
    data,
    Options options,
  }) async {
      // ....
  }

我们需要用到三个参数:

  • urlPath : 文件地址

  • savePath : 保存路径

  • onReceiveProgress : 下载进度回调

 

03

实现下载功能

1、添加依赖

要实现文件下载功能,需要先引用一些相关的依赖:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#文件路径管理path_provider: ^1.0.1
#权限检查(android)simple_permissions: ^0.1.9
#文件管理file_utils: ^0.1.3

 

2、android 端需要加入相关的权限

由于下载文件涉及到了磁盘读写等,因此需要加入读写权限。在 AndroidManifext.xml 加入权限:

  •  
  •  
  •  
<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

3、实现下载文件的功能

 

Future<void> downloadFile() async {
    Dio dio = Dio();
    bool checkPermission1 =
    //1、权限检查
    await SimplePermissions.checkPermission(permission1);
    if (checkPermission1 == false) {
      await SimplePermissions.requestPermission(permission1);
      checkPermission1 = await SimplePermissions.checkPermission(permission1);
    }

    if (checkPermission1 == true) {
      String dirloc = "";
      if (Platform.isAndroid) {
        dirloc = "/sdcard/download/";
      } else {
        dirloc = (await getApplicationDocumentsDirectory()).path;
      }

      var randid = random.nextInt(10000);

      try {

        //2、创建文件
        FileUtils.mkdir([dirloc]);

        //3、使用 dio 下载文件
        await dio.download(fileURl, dirloc + randid.toString() + ".mp3",
            onReceiveProgress: (receivedBytes, totalBytes) {
              setState(() {
                downloading = true;
                // 4、连接资源成功开始下载后更新状态
                progress = (receivedBytes / totalBytes) ;
              });
            });

      } catch (e) {
        print(e);
      }


      setState(() {
        downloading = false;
        progress = 0;
        path = dirloc + randid.toString() + ".mp3";
      });


    } else {
      setState(() {
        progress = 0;
        _onPressed = () {
          downloadFile();
        };
      });
    }
  }
 

最主要的步骤有:

  • Android 端的权限检查,这个需要根据是否有权限进一步处理(进行下一步,或者重新申请权限)

  • 在指定的目录中先创建文件

  • 使用 Dio 开始下载文件

  • 开始下载之后,通过 setState 更新进度

 

4、UI 的更新

 

Container(
child: downloading
    ? Container(
  height: 200.0,
  width: 200.0,
  child:
  Padding(
    padding: EdgeInsets.all(10),
    child:
    SizedBox(
      width: 200,
      height: 200,
      child:
      CircularProgressIndicator(
        backgroundColor: Colors.grey[200],
        value: progress,
      ),
    ),
  ),

)
    : Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Text("下载文件路径:" + path),
    MaterialButton(
      child: Text('开始下载文件'),
      onPressed: (){
        downloadFile();
      },
      disabledColor: Colors.blueGrey,
      color: Colors.pink,
      textColor: Colors.white,
      height: 40.0,
      minWidth: 100.0,
    ),
  ],
)
)

 

这里只是为了演示,仅仅通过一个变量来决定显示什么组件,也是通过 progress 这个变量来标识进度(通过 setState 来更新)。

效果:

 

 

github 地址:

https://github.com/hcc007/FlutterShare

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Flutter 是一个跨平台的移动应用程序开发框架,可以快速构建具备丰富用户界面和功能的应用程序。在Flutter的开发中,文件下载是不可避免的需求,经常遇到需要下载文件的场景,例如下载图片、音频以及视频等媒体文件或其他数据文件。 Flutter 提供了许多第三方库来实现文件下载,常用的有http、dio等库,这些库都可以配合Flutter的异步特性来下载文件,并提供了丰富的参数设置和进度回调信息。 在使用http库进行文件下载时,可以通过设置请求头信息为字节范围来支持断点续传,即如果下载中断可以继续下载,避免重复下载浪费流量和时间。同时,还可以通过设置连接和读取超时时间等参数来优化下载体验。使用http库下载文件的代码示例如下: ``` import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:io'; import 'dart:async'; class DownloadFile extends StatefulWidget { @override _DownloadFileState createState() => _DownloadFileState(); } class _DownloadFileState extends State<DownloadFile> { String downloadUrl = "http://www.example.com/file.mp3"; String savePath = Directory.systemTemp.path + "/file.mp3"; Future<void> _downloadFile(String url, String savePath) async { final response = await http.get(url, headers: { HttpHeaders.rangeHeader: "bytes=${File(savePath).lengthSync()}-" }).timeout(Duration(seconds: 30)); if (response.statusCode == 200 || response.statusCode == 206) { File(savePath).writeAsBytesSync(response.bodyBytes, mode: FileMode.append); } else { throw Exception("Download failed: ${response.statusCode}"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Download file example"), ), body: Center( child: RaisedButton( onPressed: () { _downloadFile(downloadUrl, savePath); }, child: Text("Download file"), ), ), ); } } ``` 在上述代码中,使用dio库下载文件也可以实现类似的功能,而且dio库有更加方便的操作和更加详细的错误处理和进度监听功能。需要注意的是,使用dio库需要在pubspec.yaml文件中添加依赖库: ``` dependencies: dio: ^3.0.10 ``` 使用dio库下载文件的代码示例如下: ``` import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; import 'dart:io'; import 'dart:async'; class DownloadFile extends StatefulWidget { @override _DownloadFileState createState() => _DownloadFileState(); } class _DownloadFileState extends State<DownloadFile> { String downloadUrl = "http://www.example.com/file.mp3"; String savePath = Directory.systemTemp.path + "/file.mp3"; Future<void> _downloadFile(String url, String savePath) async { Dio dio = Dio(); try { Response response = await dio.download( url, savePath, onReceiveProgress: (count, total) => print("Received $count bytes out of $total"), options: Options(headers: { HttpHeaders.rangeHeader: "bytes=${File(savePath).lengthSync()}-" }), ); } catch (e) { throw Exception("Download failed: $e"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Download file example"), ), body: Center( child: RaisedButton( onPressed: () { _downloadFile(downloadUrl, savePath); }, child: Text("Download file"), ), ), ); } } ``` 综上所述,Flutter提供了多种库可以实现文件下载功能,选择合适的库可以有效地提升下载效率和下载体验,进一步提升应用的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值