如何在加载文件后执行 Navigator.push 操作(在此过程中使用 CircularProgressIndicator())?
How to implement Navigator.push action after loading file (using CircularProgressIndicator() during the process)?
在显示 CircularProgressIndicator()
并在成功加载文件后使用 Navigator.pushNamedAndRemoveUntil
的同时实现文件后台下载的“最佳实践”方法是什么?
这是我的代码示例:
class Downloader extends StatefulWidget {
const Downloader({Key? key}) : super(key: key);
@override
DownloaderState createState() => DownloaderState();
}
class DownloaderState extends State<Downloader> {
Future<Directory?>? _appDocumentsDirectory;
bool _isDownloaded = false;
@override
void initState() {
super.initState();
_initDownloader();
}
_initDownloader() async {
setState(() {
_appDocumentsDirectory = getApplicationDocumentsDirectory();
});
}
Future<void> _downloadJson(String localPath) async {
if ( === WE CHECK FOR CREDENTIALS HERE === ) {
FTPConnect ftpConnect = FTPConnect(
BaseAPI.ftpServerAddress,
port: BaseAPI.ftpServerPort,
user: _login,
pass: _passwd);
try {
String fileName = 'filename.json';
String localFileName = localPath + "/filename.json";
print(" localFileName: $localFileName");
await ftpConnect.connect();
await ftpConnect.changeDirectory('ftp');
bool res = await ftpConnect.downloadFileWithRetry(
fileName, File(localFileName));
await ftpConnect.disconnect();
print("is downloaded? $res");
} catch (e) {
print("=== ERROR ===\n${e.toString()}");
}
_isDownloaded = true;
} else {
_isDownloaded = false;
}
}
Widget _buildDirectory(
BuildContext context, AsyncSnapshot<Directory?> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
String _s = snapshot.data!.path + "/filename.json";
String _z = "File downloaded";
_downloadJson(snapshot.data!.path); ////////////// <= downloading here
if (!_isDownloaded) {
_z = "Failed to download file";
}
text = Text('Path to a file: \n$_s\n\npath: \n${snapshot.data!.path}\n\nFile downloaded: $_isDownloaded');
} else {
text = const Text('path unavailable');
}
}
return text;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Loading data"),
foregroundColor: Colors.black,
backgroundColor: Colors.redAccent,
),
body: Center(
child: Column(
children: <Widget>[
FutureBuilder<Directory?>(
future: _appDocumentsDirectory,
builder: _buildDirectory,
/// I need to redirect to another page here
),
],
),
),
);
}
}
所以我的主要问题是:
- 如何正确'catch'下载文件的时刻?我只能在控制台 (Android Studio) 中看到打印“已下载?是的”,但我不明白如何捕捉这一刻和 link 对它的一些操作...
据我了解,工作流程是这样的:
1. initialize the `_appDocumentsDirectory`;
2. on initialization start the `FutureBuilder` logic:
2.1 - checking if `_appDocumentsDirectory` has data and
2.2 - calling the `_downloadJson`
我也可以(或应该)将逻辑包装在 FutureBuilder 的 _downloadJson
函数中吗?
如果我能以某种方式解决第一个和第二个问题 - 您通常如何在需要时执行所需的 Navigator.pushNamedAndRemoveUntil()
?
先回答下面的问题,
如何在下载文件的时候显示一个CircularProgressIndicator,可以简单的引入一个变量isDownloading
如下,
bool isDownloading = false;
下载时,即
setState(() => isDownloading = true);
bool res = await ftpConnect.downloadFileWithRetry(
fileName, File(localFileName));
setState(() => isDownloading = false);
因为一旦调用 setState 就会重建主体,在主体中使用类似这样的东西,
Scaffold(
body: isDownloading ? CircularProgressIndicator() : ..[your code],
);
接下来要获取本地推送通知,您可以简单地使用 flutter_local_notifications: ^9.5.3+1
这绝对可以解决问题
在显示 CircularProgressIndicator()
并在成功加载文件后使用 Navigator.pushNamedAndRemoveUntil
的同时实现文件后台下载的“最佳实践”方法是什么?
这是我的代码示例:
class Downloader extends StatefulWidget {
const Downloader({Key? key}) : super(key: key);
@override
DownloaderState createState() => DownloaderState();
}
class DownloaderState extends State<Downloader> {
Future<Directory?>? _appDocumentsDirectory;
bool _isDownloaded = false;
@override
void initState() {
super.initState();
_initDownloader();
}
_initDownloader() async {
setState(() {
_appDocumentsDirectory = getApplicationDocumentsDirectory();
});
}
Future<void> _downloadJson(String localPath) async {
if ( === WE CHECK FOR CREDENTIALS HERE === ) {
FTPConnect ftpConnect = FTPConnect(
BaseAPI.ftpServerAddress,
port: BaseAPI.ftpServerPort,
user: _login,
pass: _passwd);
try {
String fileName = 'filename.json';
String localFileName = localPath + "/filename.json";
print(" localFileName: $localFileName");
await ftpConnect.connect();
await ftpConnect.changeDirectory('ftp');
bool res = await ftpConnect.downloadFileWithRetry(
fileName, File(localFileName));
await ftpConnect.disconnect();
print("is downloaded? $res");
} catch (e) {
print("=== ERROR ===\n${e.toString()}");
}
_isDownloaded = true;
} else {
_isDownloaded = false;
}
}
Widget _buildDirectory(
BuildContext context, AsyncSnapshot<Directory?> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
String _s = snapshot.data!.path + "/filename.json";
String _z = "File downloaded";
_downloadJson(snapshot.data!.path); ////////////// <= downloading here
if (!_isDownloaded) {
_z = "Failed to download file";
}
text = Text('Path to a file: \n$_s\n\npath: \n${snapshot.data!.path}\n\nFile downloaded: $_isDownloaded');
} else {
text = const Text('path unavailable');
}
}
return text;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Loading data"),
foregroundColor: Colors.black,
backgroundColor: Colors.redAccent,
),
body: Center(
child: Column(
children: <Widget>[
FutureBuilder<Directory?>(
future: _appDocumentsDirectory,
builder: _buildDirectory,
/// I need to redirect to another page here
),
],
),
),
);
}
}
所以我的主要问题是:
- 如何正确'catch'下载文件的时刻?我只能在控制台 (Android Studio) 中看到打印“已下载?是的”,但我不明白如何捕捉这一刻和 link 对它的一些操作...
据我了解,工作流程是这样的:
1. initialize the `_appDocumentsDirectory`;
2. on initialization start the `FutureBuilder` logic:
2.1 - checking if `_appDocumentsDirectory` has data and
2.2 - calling the `_downloadJson`
我也可以(或应该)将逻辑包装在 FutureBuilder 的
_downloadJson
函数中吗?如果我能以某种方式解决第一个和第二个问题 - 您通常如何在需要时执行所需的
Navigator.pushNamedAndRemoveUntil()
?
先回答下面的问题,
如何在下载文件的时候显示一个CircularProgressIndicator,可以简单的引入一个变量isDownloading
如下,
bool isDownloading = false;
下载时,即
setState(() => isDownloading = true);
bool res = await ftpConnect.downloadFileWithRetry(
fileName, File(localFileName));
setState(() => isDownloading = false);
因为一旦调用 setState 就会重建主体,在主体中使用类似这样的东西,
Scaffold(
body: isDownloading ? CircularProgressIndicator() : ..[your code],
);
接下来要获取本地推送通知,您可以简单地使用 flutter_local_notifications: ^9.5.3+1
这绝对可以解决问题