【问题标题】:How can I navigate to another page after CircularProgressIndicator completed in Flutter?在 Flutter 中完成 CircularProgressIndicator 后如何导航到另一个页面?
【发布时间】: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上传图片和表单
  • 添加您的上传方法代码

标签: flutter flutter-layout flutter-animation flutter-navigation flutter-widget


【解决方案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))
                            ],
                          ))
                    ],
                  )
                ],
              ),
            );
          }
        }
    

    闪屏

    主屏幕

    【讨论】:

      猜你喜欢
      • 2023-02-14
      • 2011-06-06
      • 1970-01-01
      • 2021-09-11
      • 2020-09-03
      • 2020-09-02
      • 2020-09-26
      • 2020-08-06
      • 1970-01-01
      相关资源
      最近更新 更多