在 Flutter 中完成 CircularProgressIndicator 后如何导航到另一个页面?
Posted
技术标签:
【中文标题】在 Flutter 中完成 CircularProgressIndicator 后如何导航到另一个页面?【英文标题】:How can I navigate to another page after CircularProgressIndicator completed in Flutter? 【发布时间】:2020-05-24 06:17:31 【问题描述】:您好,我是 Flutter 的新手,目前正在构建一个聊天应用程序。
我有一个配置文件制作器屏幕,用户可以在其中上传图像来设置他们的头像。我正在使用CircularProgressIndicator()
显示上传屏幕。我想知道如何在上传完成后自动导航到下一个屏幕,即我的主屏幕,这样用户就不必等待按下任何按钮。
这是我尝试过的代码
progressString != '100% Completed' ? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Colors.blue,
),
SizedBox(
height: 20.0,
),
Text("Uploading File : $progressString",
style: TextStyle(
color: Colors.white54,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
),
],
) : Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context)
return LoginPage();
),
),
上传代码
FormData data = FormData.fromMap(
"username": userName.toString(),
"name": naMe.toString(),
"birthday": birthDay.toString(),
"about": aboutUser.toString(),
"sender": sendUser.toString(),
"mobile": userMobile.toString(),
"avatar": _image != null
? await MultipartFile.fromFile(_image.path,
filename: avatarName.toString())
: Text('Invalid Avatar'),
);
if (_validateAndSave())
final token = widget.token;
try
Dio dio = Dio();
dio.options.headers['Accept'] = "application/json";
dio.options.headers['Authorization'] = "Bearer $token";
dio.options.headers['Content-Type'] = "multipart/form-data";
dio.options.followRedirects = false;
var response = await dio.post(url,
data: data, onSendProgress: (int rec, int total)
setState(()
uploading = true;
progressString = ((rec / total * 100).toString());
);
);
var responseCode = response.statusCode;
print('Dio responseCode : $responseCode');
on DioError catch (err)
var responseCode = err.response.statusCode;
print(responseCode);
setState(()
uploading = false;
progressString = "100% Completed ";
print(progressString);
);
【问题讨论】:
添加您的代码,我们可以帮助您 你现在能帮忙吗.....我附上了我试过的代码...... 如何上传图片到服务器? 我使用formdata和multipartfile上传图片和表单 添加您的上传方法代码 【参考方案1】:上传完成后,您应该在上传功能中设置导航器
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Colors.blue,
),
SizedBox(
height: 20.0,
),
Text("Uploading File : $progressString",
style: TextStyle(
color: Colors.white54,
fontSize: 20.0,
fontWeight: FontWeight.w900,
),
),
],
),
FormData data = FormData.fromMap(
"username": userName.toString(),
"name": naMe.toString(),
"birthday": birthDay.toString(),
"about": aboutUser.toString(),
"sender": sendUser.toString(),
"mobile": userMobile.toString(),
"avatar": _image != null
? await MultipartFile.fromFile(_image.path,
filename: avatarName.toString())
: Text('Invalid Avatar'),
);
if (_validateAndSave())
final token = widget.token;
try
Dio dio = Dio();
dio.options.headers['Accept'] = "application/json";
dio.options.headers['Authorization'] = "Bearer $token";
dio.options.headers['Content-Type'] = "multipart/form-data";
dio.options.followRedirects = false;
var response = await dio.post(url,
data: data, onSendProgress: (int rec, int total)
setState(()
uploading = true;
progressString = ((rec / total * 100).toString());
);
);
var responseCode = response.statusCode;
print('Dio responseCode : $responseCode');
on DioError catch (err)
var responseCode = err.response.statusCode;
print(responseCode);
Future.delaye(Duration(milliseconds: 100), ()
Navigator.pushReplacement(this.context,
MaterialPageRoute(builder: (context)
return LoginPage();
),
);
);
【讨论】:
查找已停用小部件的祖先是不安全的。此时小部件的元素树的状态不再稳定。要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。 上传完成后将导航器放入上传函数后出现此类错误。 [VERBOSE-2:ui_dart_state.cc(157)] 未处理的异常:查找已停用小部件的祖先是不安全的。此时小部件的元素树的状态不再稳定。要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。 [VERBOSE-2:ui_dart_state.cc(157)] 未处理的异常:查找已停用小部件的祖先是不安全的。此时小部件的元素树的状态不再稳定。要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。 谢谢你,维内诺。你做到了我想要的,非常感谢伙计.....【参考方案2】:上传完成后,更新 UI 以向用户显示上传完成并添加后帧回调以导航到下一页。 p>
【讨论】:
【参考方案3】:第 1 步:在 lib 文件夹下创建一个新文件,即 splashscreen.dart 文件。在 main.dart 文件中引用 SplashScreen()。
文件名:main.dart
import 'package:flutter/material.dart';
import 'package:mfitz/splashscreen.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
);
第 2 步:在 splashscreen.dart 文件下创建启动屏幕所需的 UI,并在 void initState() 方法下包含以下代码,以在 5 秒后导航到新屏幕。
Timer(Duration(seconds: 5), ()
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (_) => MainScreen()));
启动画面代码
文件名:splashscreen.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'mainScreen.dart';
class SplashScreen extends StatefulWidget
@override
_SplashScreenState createState() => _SplashScreenState();
class _SplashScreenState extends State<SplashScreen>
@override
void initState()
super.initState();
//Navigates to new screen after 5 seconds.
Timer(Duration(seconds: 5), ()
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (_) => MainScreen()));
);
@override
Widget build(BuildContext context)
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
image: new DecorationImage(
image: AssetImage('assets/images/img2.jpg'),
fit: BoxFit.fill,
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: Colors.grey[100],
radius: 80.0,
child: Text(
"MOBIFIT.",
style: GoogleFonts.aldrich(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 30.0),
textAlign: TextAlign.center,
),
),
],
),
),
),
Expanded(
flex: 1,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(right: 100.0, left: 100.0),
child: LinearProgressIndicator(
backgroundColor: Colors.white,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.grey),
minHeight: 10.0,
),
),
Padding(padding: EdgeInsets.only(bottom: 10.0))
],
))
],
)
],
),
);
闪屏
主屏幕
【讨论】:
以上是关于在 Flutter 中完成 CircularProgressIndicator 后如何导航到另一个页面?的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中完成 CircularProgressIndicator 后如何导航到另一个页面?
在 Flutter 中完成“构建”功能时是不是有任何回调告诉我?
(Flutter) 如何在不按“完成”的情况下自动监听 TextField 中的变化?