Flutter 實現檔案下載功能

Flutter程式設計開發發表於2020-05-03

一、Flutter 中的進度指示器

Material 庫中進度指示器有兩個 :

  • LinearProgressIndicator : 線性進度條指示器
  • CircularProgressIndicator : 圓環進度條指示器

這兩個指示器都有精準精度和模糊精度兩種模式。

1、LinearProgressIndicator

定義如下 :

LinearProgressIndicator({
  double value,
  Color backgroundColor,
  Animation<Color> valueColor,
  ...
})
複製程式碼
  • 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,

      ),
    ),

  ),

複製程式碼

效果:

Flutter 實現檔案下載功能

二、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 : 下載進度回撥

三、實現下載功能

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" />
複製程式碼

Flutter 實現檔案下載功能

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 來更新)。

效果:

Flutter 實現檔案下載功能


github 地址

最後

歡迎關注「Flutter 程式設計開發」微信公眾號 。

Flutter 實現檔案下載功能

相關文章