Как я могу перейти на другую страницу после завершения CircularProgressIndicator во Flutter?

Здравствуйте, я новичок во 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);
    });
  }

3 ответа

Решение

Вы должны установить свой навигатор внутри своей функции загрузки после завершения загрузки

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();
             }),
          );
      });
  }

When the upload is complete, update the UI to show the user that the upload is complete and add a post frame callback to navigate to the next page.

Шаг 1: Создайте новый файл, то есть файл splashscreen.dart в папке lib. В файле 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 создайте необходимый пользовательский интерфейс для экрана-заставки и включите следующий код в метод 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))
                        ],
                      ))
                ],
              )
            ],
          ),
        );
      }
    }

ЗАСТАВКА

ГЛАВНЫЙ ЭКРАН

Другие вопросы по тегам