Як працювати з показником прогресу у флаттері?


86

Я новачок у метушні і хотів би знати, що найкращий спосіб додати CircularProgressIndicatorдо мого макета. Наприклад, мій режим входу. У цьому поданні є ім’я користувача, пароль та кнопка входу. Я хотів створити накладений макет (with Opacity), який під час завантаження відображає індикатор прогресу, як я використовую в NativeScript, але я трохи не плутаюся з тим, як це робити, і теж, якщо це кращий спосіб. Наприклад, у NativeScript я додаю IndicatorActivity в основний макет і встановлюю зайнятий на true або false, тому він накладає всі компоненти подання під час завантаження.

Редагувати:

Мені вдалося досягти такого результату:

    void main() {
      runApp(new MyApp());
    }

    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);

      final String title;

      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
      bool _loading = false;

      void _onLoading() {
        setState(() {
          _loading = true;
          new Future.delayed(new Duration(seconds: 3), _login);
        });
      }


      Future _login() async{
        setState((){
          _loading = false;
        });
      }

      @override
      Widget build(BuildContext context) {


          var body = new Column(
              children: <Widget>[
                new Container(
                  height: 40.0,
                  padding: const EdgeInsets.all(10.0),
                  margin: const EdgeInsets.fromLTRB(15.0, 150.0, 15.0, 0.0),
                  decoration: new BoxDecoration(
                    color: Colors.white,
                  ),
                  child: new TextField(
                    decoration: new InputDecoration.collapsed(hintText: "username"),
                  ),
                ),
                new Container(
                  height: 40.0,
                  padding: const EdgeInsets.all(10.0),
                  margin: const EdgeInsets.all(15.0),
                  decoration: new BoxDecoration(
                    color: Colors.white,
                  ),
                  child: new TextField(
                    decoration: new InputDecoration.collapsed(hintText: "password"),
                  ),
                ),
              ],
            );


          var bodyProgress = new Container(
            child: new Stack(
              children: <Widget>[
                body,
                new Container(
                  alignment: AlignmentDirectional.center,
                  decoration: new BoxDecoration(
                    color: Colors.white70,
                  ),
                  child: new Container(
                    decoration: new BoxDecoration(
                      color: Colors.blue[200],
                      borderRadius: new BorderRadius.circular(10.0)
                    ),
                    width: 300.0,
                    height: 200.0,
                    alignment: AlignmentDirectional.center,
                    child: new Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        new Center(
                          child: new SizedBox(
                            height: 50.0,
                            width: 50.0,
                            child: new CircularProgressIndicator(
                              value: null,
                              strokeWidth: 7.0,
                            ),
                          ),
                        ),
                        new Container(
                          margin: const EdgeInsets.only(top: 25.0),
                          child: new Center(
                            child: new Text(
                              "loading.. wait...",
                              style: new TextStyle(
                                color: Colors.white
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          );

          return new Scaffold(
            appBar: new AppBar(
              title: new Text(widget.title),
            ),
            body: new Container(
              decoration: new BoxDecoration(
                color: Colors.blue[200]
              ),
              child: _loading ? bodyProgress : body
            ),
            floatingActionButton: new FloatingActionButton(
              onPressed: _onLoading,
              tooltip: 'Loading',
              child: new Icon(Icons.check),
            ),
          );
      }
    }

результат екрану програми

Я все ще адаптуюся до ідеї держав. Цей код знаходиться в межах очікуваного при роботі з флаттером?

Дякую!


1
як відключити зворотне натискання під час відображення діалогового вікна?
Швидко навчається

Відповіді:


77

У метушні є кілька способів боротися з асинхронними діями.

Ледачий спосіб зробити це може бути використання модалів. Що заблокує введення користувачем, тим самим запобігаючи небажаним діям. Для цього потрібно дуже мало змінити ваш код. Просто модифікуйте свій файл _onLoadingприблизно так:

void _onLoading() {
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return Dialog(
        child: new Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            new CircularProgressIndicator(),
            new Text("Loading"),
          ],
        ),
      );
    },
  );
  new Future.delayed(new Duration(seconds: 3), () {
    Navigator.pop(context); //pop dialog
    _login();
  });
}

Найбільш ідеальний спосіб зробити це за FutureBuilderдопомогою віджета, що містить статус. З чого ви почали. Фокус у тому, що замість того, щоб мати boolean loading = falseу своєму штаті, ви можете безпосередньо використовуватиFuture<MyUser> user

А потім передайте його як аргумент FutureBuilder, який дасть вам деяку інформацію, таку як "hasData" або примірник MyUserзавершення.

Це призвело б до приблизно такого:

@immutable
class MyUser {
  final String name;

  MyUser(this.name);
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Future<MyUser> user;

  void _logIn() {
    setState(() {
      user = new Future.delayed(const Duration(seconds: 3), () {
        return new MyUser("Toto");
      });
    });
  }

  Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
    var floatBtn = new RaisedButton(
      onPressed:
          snapshot.connectionState == ConnectionState.none ? _logIn : null,
      child: new Icon(Icons.save),
    );
    var action =
        snapshot.connectionState != ConnectionState.none && !snapshot.hasData
            ? new Stack(
                alignment: FractionalOffset.center,
                children: <Widget>[
                  floatBtn,
                  new CircularProgressIndicator(
                    backgroundColor: Colors.red,
                  ),
                ],
              )
            : floatBtn;

    return new ListView(
      padding: const EdgeInsets.all(15.0),
        children: <Widget>[
          new ListTile(
            title: new TextField(),
          ),
          new ListTile(
            title: new TextField(obscureText: true),
          ),
          new Center(child: action)
        ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return new FutureBuilder(
      future: user,
      builder: (context, AsyncSnapshot<MyUser> snapshot) {
        if (snapshot.hasData) {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text("Hello ${snapshot.data.name}"),
            ),
          );
        } else {
          return new Scaffold(
            appBar: new AppBar(
              title: new Text("Connection"),
            ),
            body: _buildForm(snapshot),
          );
        }
      },
    );
  }
}

1
Класно, обидва приклади будуть корисні для входу та інших ситуацій. Прогрес обробника з діалоговим вікном виглядає краще, ніж моя версія, а FutureBuilder Це також елегантніше, ніж моє рішення. дякую за допомогу!
Рікардо Боккі,

питання поза темою .. для кожного TextField мені потрібен унікальний TextEditingController?
Рікардо Боккі,

@RicardoBocchi Так
aziza

Я не думаю, що діалогове вікно буде працювати з фактичним прикладом, це бентежить, як користувач буде перенаправлений після повернення _login (). Ваш другий приклад, проте, здається набагато зручнішим. Добре пропечена.
aziza

1
Ну, Діалогове вікно функціональне і вимагає дуже незначних змін до його вихідного коду. Наприклад, він міг стежити за діалоговим вікном, закритим за допомогою Navigator.pushNamed("/home").
Ремі Русселет

38

Для мене один акуратний спосіб це зробити - показати SnackBarвнизу, поки відбувається процес входу, це приклад того, що я маю на увазі:

введіть тут опис зображення

Ось як налаштувати SnackBar.

Визначте загальний ключ для вашого Scaffold

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

Додайте його до свого Scaffold keyатрибута

return new Scaffold(
      key: _scaffoldKey,
.......

Зворотний onPressedдзвінок на кнопку «Увійти»

onPressed: () {
                  _scaffoldKey.currentState.showSnackBar(
                      new SnackBar(duration: new Duration(seconds: 4), content:
                      new Row(
                        children: <Widget>[
                          new CircularProgressIndicator(),
                          new Text("  Signing-In...")
                        ],
                      ),
                      ));
                  _handleSignIn()
                      .whenComplete(() =>
                      Navigator.of(context).pushNamed("/Home")
                  );
                }

Це справді залежить від того, як ви хочете побудувати свій макет, і я не впевнений, що ви маєте на увазі.

Редагувати

Ви, мабуть, хочете, щоб це було таким чином, я використав стек для досягнення цього результату і просто показав або приховав свій індикатор на основі onPressed

введіть тут опис зображення

class TestSignInView extends StatefulWidget {
  @override
  _TestSignInViewState createState() => new _TestSignInViewState();
}


class _TestSignInViewState extends State<TestSignInView> {
  bool _load = false;
  @override
  Widget build(BuildContext context) {
    Widget loadingIndicator =_load? new Container(
      color: Colors.grey[300],
      width: 70.0,
      height: 70.0,
      child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
    ):new Container();
    return new Scaffold(
      backgroundColor: Colors.white,
      body:  new Stack(children: <Widget>[new Padding(
        padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
        child: new ListView(

          children: <Widget>[
            new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center
              ,children: <Widget>[
            new TextField(),
            new TextField(),

            new FlatButton(color:Colors.blue,child: new Text('Sign In'),
                onPressed: () {
              setState((){
                _load=true;
              });

                  //Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
                }
            ),

            ],),],
        ),),
        new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

      ],));
  }

}

Привіт, це те, що я хотів зробити, але я не отримав потрібний макет. Стек - це відповідь. Про StatefulWidget, чи правильно будувати всі подання, коли стан прогресу змінюється?
Рікардо Боккі,

Гей, я не розумію вашого запитання?
aziza

У моєму коді при _loadingзміні всі перегляди відновлюються. Невже це так?
Рікардо Боккі,

1
Використовувати модальний, можливо, набагато простіше і одночасно інтуїтивніше. Ви можете просто натиснути діалогове вікно завантаження на початку або на ваш запит і розгорнути його, коли закінчите. Він також має ту перевагу, що запобігає подальшому введенню користувачем.
Rémi Rousselet

2
Гаразд, дозволь мені щось спекти.
Rémi Rousselet

34

Створіть bool isLoadingі встановіть для нього значення false. За допомогою тернарного оператора, коли користувач натискає кнопку входу, встановіть стан isLoadingна true. Ви отримаєте індикатор кругового завантаження замість кнопки входу

 isLoading ? new PrimaryButton(
                      key: new Key('login'),
                      text: 'Login',
                      height: 44.0,
                      onPressed: setState((){isLoading = true;}))
                  : Center(
                      child: CircularProgressIndicator(),
                    ),

Ви можете побачити знімки екрану, як це виглядає, до того як клацнути на логіні введіть тут опис зображення

Після натискання на логін введіть тут опис зображення

Тим часом ви можете запустити процес входу та входу користувача. Якщо облікові дані невірні , то ви знову будете setStateв , isLoadingщоб false, таким чином, щоб індикатор завантаження стане невидимим і Ввійти кнопку видимою для користувача. До речі, PrimaryButton, що використовується в коді, - це моя спеціальна кнопка. Ви можете зробити те ж саме з OnPressedin button.


Це насправді досить розумно! Не потрібно обробляти подвійне клацання тощо. Дякую.
Бенобаб,

як впоратися з подвійним клацанням у пурханні, як у цьому випадку?

Я ніколи не отримував такої ситуації, щоб обробляти подвійне натискання, оскільки при одному натисканні воно змінюється на індикатор завантаження. Відповідно до мого розуміння Вашого коментаря, я думаю, що ми можемо обернути спеціальну кнопку детектором жестів, і тоді Ви зможете двічі натиснути там.
Harsha pulikollu

Де використовувати тернарний оператор? Ваш приклад виглядає розумно, але не впевнений, як його реалізувати.
Bikram Pahi

Використовуйте згаданий вище фрагмент коду в методі побудови, де ви хочете мати кнопку (вхід). Коли користувач натискає цю кнопку, bool (isLoading) стає істинним і замість кнопки показує індикатор кругового завантаження.
Harsha pulikollu

20

1. Без плагіна

    class IndiSampleState extends State<ProgHudPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('Demo'),
        ),
        body: Center(
          child: RaisedButton(
            color: Colors.blueAccent,
            child: Text('Login'),
            onPressed: () async {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return Center(child: CircularProgressIndicator(),);
                  });
              await loginAction();
              Navigator.pop(context);
            },
          ),
        ));
  }

  Future<bool> loginAction() async {
    //replace the below line of code with your login request
    await new Future.delayed(const Duration(seconds: 2));
    return true;
  }
}

2. З плагіном

перевірте цей плагін progress_hud

додати залежність у файл pubspec.yaml

dev_dependencies:
  progress_hud: 

імпортувати пакет

import 'package:progress_hud/progress_hud.dart';

Зразок коду наведено нижче, щоб показати та приховати індикатор

class ProgHudPage extends StatefulWidget {
  @override
  _ProgHudPageState createState() => _ProgHudPageState();
}

class _ProgHudPageState extends State<ProgHudPage> {
  ProgressHUD _progressHUD;
  @override
  void initState() {
    _progressHUD = new ProgressHUD(
      backgroundColor: Colors.black12,
      color: Colors.white,
      containerColor: Colors.blue,
      borderRadius: 5.0,
      loading: false,
      text: 'Loading...',
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('ProgressHUD Demo'),
        ),
        body: new Stack(
          children: <Widget>[
            _progressHUD,
            new Positioned(
                child: RaisedButton(
                  color: Colors.blueAccent,
                  child: Text('Login'),
                  onPressed: () async{
                    _progressHUD.state.show();
                    await loginAction();
                    _progressHUD.state.dismiss();
                  },
                ),
                bottom: 30.0,
                right: 10.0)
          ],
        ));
  }

  Future<bool> loginAction()async{
    //replace the below line of code with your login request
    await new Future.delayed(const Duration(seconds: 2));
    return true;
  }
}

12
Не голосуйте за це, деякі люди не хочуть обробляти дрібні деталі інтерфейсу користувача, і я один із них, тому цей плагін стане в нагоді
Vladtn,

3
бар прогресу в api досить справедливий, додавання залежності збільшує розмір збірки. вже пурхання нарощування надмірне.
prashant0205

Ви дійсно повинні додати це як залежність від розробника?
Джордж

перевірити на останньому прикладі pub.dartlang.org/packages/progress_hud#-example-tab-
Shyju M

1
@MohammadMeshkani використовують Navigator.pop (контекст); перед
переходом

13

Крок 1: Створіть діалогове вікно

   showAlertDialog(BuildContext context){
      AlertDialog alert=AlertDialog(
        content: new Row(
            children: [
               CircularProgressIndicator(),
               Container(margin: EdgeInsets.only(left: 5),child:Text("Loading" )),
            ],),
      );
      showDialog(barrierDismissible: false,
        context:context,
        builder:(BuildContext context){
          return alert;
        },
      );
    }

Крок 2: Зателефонуйте

showAlertDialog(context);
await firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
Navigator.pop(context);

Приклад з діалоговим вікном та формою входу

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class DynamicLayout extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new MyWidget();
    }
  }
showAlertDialog(BuildContext context){
  AlertDialog alert=AlertDialog(
    content: new Row(
        children: [
           CircularProgressIndicator(),
           Container(margin: EdgeInsets.only(left: 5),child:Text("Loading" )),
        ],),
  );
  showDialog(barrierDismissible: false,
    context:context,
    builder:(BuildContext context){
      return alert;
    },
  );
}

  class MyWidget extends State<DynamicLayout>{
  Color color = Colors.indigoAccent;
  String title='app';
  GlobalKey<FormState> globalKey=GlobalKey<FormState>();
  String email,password;
  login() async{
   var currentState= globalKey.currentState;
   if(currentState.validate()){
        currentState.save();
        FirebaseAuth firebaseAuth=FirebaseAuth.instance;
        try {
          showAlertDialog(context);
          AuthResult authResult=await firebaseAuth.signInWithEmailAndPassword(
              email: email, password: password);
          FirebaseUser user=authResult.user;
          Navigator.pop(context);
        }catch(e){
          print(e);
        }
   }else{

   }
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar:AppBar(
        title: Text("$title"),
        ) ,
          body: Container(child: Form(
            key: globalKey,
            child: Container(
              padding: EdgeInsets.all(10),
              child: Column(children: <Widget>[
              TextFormField(decoration: InputDecoration(icon: Icon(Icons.email),labelText: 'Email'),
              // ignore: missing_return
              validator:(val){
                if(val.isEmpty)
                  return 'Please Enter Your Email';
              },
              onSaved:(val){
                email=val;
              },
              ),
                TextFormField(decoration: InputDecoration(icon: Icon(Icons.lock),labelText: 'Password'),
             obscureText: true,
                  // ignore: missing_return
                  validator:(val){
                    if(val.isEmpty)
                      return 'Please Enter Your Password';
                  },
                  onSaved:(val){
                    password=val;
                  },
              ),
                RaisedButton(color: Colors.lightBlue,textColor: Colors.white,child: Text('Login'),
                  onPressed:login),
            ],)
              ,),)
         ),
    );
  }
}

введіть тут опис зображення


2
Будь ласка, додайте трохи більше контексту до своєї відповіді.
Вальс смерті

10

Я застосував наступний підхід, який використовує простий віджет модального індикатора прогресу, який обертає все, що ви хочете зробити модальним під час асинхронного дзвінка.

Приклад у пакеті також стосується того, як обробляти перевірку форми під час здійснення асинхронних викликів для перевірки форми ( докладніше про цю проблему див. У flutter / issues / 9688 ). Наприклад, не залишаючи форми, цей метод перевірки асинхронної форми може бути використаний для перевірки нового імені користувача щодо існуючих імен у базі даних під час реєстрації.

https://pub.dartlang.org/packages/modal_progress_hud

Ось демонстраційний приклад з пакетом (із вихідним кодом):

перевірка асинхронної форми за допомогою модального індикатора прогресу

Приклад може бути адаптований до іншої поведінки модальних показників прогресу (наприклад, різної анімації, додаткового тексту в модальній версії тощо).


2

Це моє рішення зі стеком

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:async';

final themeColor = new Color(0xfff5a623);
final primaryColor = new Color(0xff203152);
final greyColor = new Color(0xffaeaeae);
final greyColor2 = new Color(0xffE8E8E8);

class LoadindScreen extends StatefulWidget {
  LoadindScreen({Key key, this.title}) : super(key: key);
  final String title;
  @override
  LoginScreenState createState() => new LoginScreenState();
}

class LoginScreenState extends State<LoadindScreen> {
  SharedPreferences prefs;

  bool isLoading = false;

  Future<Null> handleSignIn() async {
    setState(() {
      isLoading = true;
    });
    prefs = await SharedPreferences.getInstance();
    var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
      return false;
    });
    isLoadingFuture.then((response) {
      setState(() {
        isLoading = response;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(
            widget.title,
            style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
          ),
          centerTitle: true,
        ),
        body: Stack(
          children: <Widget>[
            Center(
              child: FlatButton(
                  onPressed: handleSignIn,
                  child: Text(
                    'SIGN IN WITH GOOGLE',
                    style: TextStyle(fontSize: 16.0),
                  ),
                  color: Color(0xffdd4b39),
                  highlightColor: Color(0xffff7f7f),
                  splashColor: Colors.transparent,
                  textColor: Colors.white,
                  padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
            ),

            // Loading
            Positioned(
              child: isLoading
                  ? Container(
                      child: Center(
                        child: CircularProgressIndicator(
                          valueColor: AlwaysStoppedAnimation<Color>(themeColor),
                        ),
                      ),
                      color: Colors.white.withOpacity(0.8),
                    )
                  : Container(),
            ),
          ],
        ));
  }
}

2

Я пропоную використовувати цей плагін flutter_easyloading

flutter_easyloading - це чистий та легкий віджет для завантаження для програми Flutter, простий у використанні без контексту, підтримка iOS та Android

Додайте це до pubspec.yamlфайлу вашого пакунку :

dependencies:
  flutter_easyloading: ^2.0.0

Тепер у коді Dart ви можете використовувати:

import 'package:flutter_easyloading/flutter_easyloading.dart';

Щоб використовувати First, ініціалізуйте FlutterEasyLoadingв MaterialApp/CupertinoApp

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import './custom_animation.dart';

import './test.dart';

void main() {
  runApp(MyApp());
  configLoading();
}

void configLoading() {
  EasyLoading.instance
    ..displayDuration = const Duration(milliseconds: 2000)
    ..indicatorType = EasyLoadingIndicatorType.fadingCircle
    ..loadingStyle = EasyLoadingStyle.dark
    ..indicatorSize = 45.0
    ..radius = 10.0
    ..progressColor = Colors.yellow
    ..backgroundColor = Colors.green
    ..indicatorColor = Colors.yellow
    ..textColor = Colors.yellow
    ..maskColor = Colors.blue.withOpacity(0.5)
    ..userInteractions = true
    ..customAnimation = CustomAnimation();
}

Потім використовуйте відповідно до ваших вимог

import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:dio/dio.dart';

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  void initState() {
    super.initState();
    // EasyLoading.show();
  }

  @override
  void deactivate() {
    EasyLoading.dismiss();
    super.deactivate();
  }

  void loadData() async {
    try {
      EasyLoading.show();
      Response response = await Dio().get('https://github.com');
      print(response);
      EasyLoading.dismiss();
    } catch (e) {
      EasyLoading.showError(e.toString());
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter EasyLoading'),
      ),
      body: Center(
        child: FlatButton(
          textColor: Colors.blue,
          child: Text('loadData'),
          onPressed: () {
            loadData();
            // await Future.delayed(Duration(seconds: 2));
            // EasyLoading.show(status: 'loading...');
            // await Future.delayed(Duration(seconds: 5));
            // EasyLoading.dismiss();
          },
        ),
      ),
    );
  }
}

введіть тут опис зображення


Де є власний клас анімації? Чи потрібно нам це включати.
Наяс Субраманіан,

Ні, це вам не потрібно, і якщо ви хочете, перейдіть за адресою
Пареш Мангукія

1

Натомість ви можете використовувати віджет FutureBuilder. Для цього потрібен аргумент, який має бути Майбутнім. Тоді ви можете використовувати знімок, який є станом на момент виклику асинхронізації при вході, після закінчення стану повернення функції асинхронізації буде оновлено, і майбутній конструктор відновиться, щоб ви могли потім запитати новий держава.

FutureBuilder(
  future:  myFutureFunction(),
  builder: (context, AsyncSnapshot<List<item>> snapshot) {
    if (!snapshot.hasData) {
      return Center(
        child: CircularProgressIndicator(),
      );
    } else {
     //Send the user to the next page.
  },
);

Ось вам приклад того, як будувати майбутнє

Future<void> myFutureFunction() async{
 await callToApi();}

1

Це можна зробити для центрального прозорого індикатора прогресу

Future<Null> _submitDialog(BuildContext context) async {
  return await showDialog<Null>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return SimpleDialog(
          elevation: 0.0,
          backgroundColor: Colors.transparent,
          children: <Widget>[
            Center(
              child: CircularProgressIndicator(),
            )
          ],
        );
      });
}

0
class Loader extends StatefulWidget {
      @override
      State createState() => LoaderState();
    }

    class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;

      @override
      void initState() {
        super.initState();
        controller = AnimationController(
            duration: Duration(milliseconds: 1200), vsync: this);
        animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
        animation.addListener(() {
          this.setState(() {});
        });
        animation.addStatusListener((AnimationStatus status) {});
        controller.repeat();
      }

      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              color: Colors.blue,
              height: 3.0,
              width: animation.value * 100.0,
            ),
            Padding(
              padding: EdgeInsets.only(bottom: 5.0),
            ),
            Container(
              color: Colors.blue[300],
              height: 3.0,
              width: animation.value * 75.0,
            ),
            Padding(
              padding: EdgeInsets.only(bottom: 5.0),
            ),
            Container(
              color: Colors.blue,
              height: 3.0,
              width: animation.value * 50.0,
            )
          ],
        );
      }
    }


    Expanded(
                        child: Padding(
                          padding:
                              EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
                          child: GestureDetector(
                            onTap: () {
                              Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                      builder: (context) => FirstScreen()));
                            },
                            child: Container(
                                alignment: Alignment.center,
                                height: 45.0,
                                decoration: BoxDecoration(
                                    color: Color(0xFF1976D2),
                                    borderRadius: BorderRadius.circular(9.0)),
                                child: Text('Login',
                                    style: TextStyle(
                                        fontSize: 20.0, color: Colors.white))),
                          ),
                        ),
                      ),

Як я можу поєднати клас, який створює індикатор завантаження, з моєю кнопкою, щоб при натисканні на нього індикатор включався і переходив на наступну сторінку?
Макс Зубко

0
{
isloading? progressIos:Container()

progressIos(int i) {
    return Container(
        color: i == 1
            ? AppColors.liteBlack
            : i == 2 ? AppColors.darkBlack : i == 3 ? AppColors.pinkBtn : '',
        child: Center(child: CupertinoActivityIndicator()));
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.