一、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,
),
),
),
複製程式碼
效果:
二、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" />
複製程式碼
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 程式設計開發」微信公眾號 。