Làm thế nào để làm việc với chỉ báo tiến độ trong nháy mắt?


88

Tôi là một người mới và muốn biết cách tốt hơn để thêm CircularProgressIndicatorvào bố cục của tôi là gì. Ví dụ, chế độ xem đăng nhập của tôi. Chế độ xem này có tên người dùng, mật khẩu và Nút đăng nhập. Tôi đã muốn tạo một bố cục lớp phủ (với Opacity) mà khi tải, hiển thị chỉ báo tiến trình giống như tôi sử dụng trong NativeScript, nhưng tôi hơi bối rối với cách thực hiện và nếu đó là cách tốt hơn. Ví dụ: trên NativeScript, tôi thêm IndicatorActivity trong bố cục chính và đặt bận thành true hoặc false, vì vậy nó phủ lên tất cả các thành phần chế độ xem khi đang tải.

Biên tập:

Tôi đã có thể đạt được kết quả này:

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

kết quả màn hình ứng dụng

Tôi vẫn đang thích nghi với ý tưởng về các trạng thái. Mã này nằm trong dự kiến ​​khi làm việc với Flagship?

Cảm ơn!


1
làm thế nào để vô hiệu hóa backpressed khi hộp thoại đang hiển thị?
học nhanh

Câu trả lời:


78

Trong rung động, có một số cách để đối phó với các hành động Không đồng bộ.

Một cách lười biếng để làm điều đó có thể là sử dụng một phương thức. Điều này sẽ chặn đầu vào của người dùng, do đó ngăn chặn bất kỳ hành động không mong muốn nào. Điều này sẽ yêu cầu rất ít thay đổi đối với mã của bạn. Chỉ cần sửa đổi của bạn _onLoadingthành một cái gì đó như thế này:

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

Cách lý tưởng nhất để làm điều đó là sử dụng FutureBuildervà một widget trạng thái. Đó là những gì bạn bắt đầu. Bí quyết là, thay vì có boolean loading = falsetrạng thái của bạn, bạn có thể trực tiếp sử dụngFuture<MyUser> user

Và sau đó chuyển nó làm đối số FutureBuilder, sẽ cung cấp cho bạn một số thông tin như "hasData" hoặc phiên bản củaMyUser khi hoàn thành.

Điều này sẽ dẫn đến một cái gì đó như thế này:

@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
Tuyệt vời, cả hai ví dụ sẽ hữu ích khi đăng nhập và các tình huống khác. Tiến trình xử lý với hộp thoại trông đẹp hơn phiên bản của tôi và FutureBuilder Nó cũng thanh lịch hơn giải pháp của tôi. cảm ơn vì sự giúp đỡ!
Ricardo Bocchi

một câu hỏi lạc đề .. với mỗi TextField tôi cần một TextE EditController duy nhất?
Ricardo Bocchi

@RicardoBocchi Có
aziza

Tôi không nghĩ Hộp thoại sẽ hoạt động với ví dụ thực tế, thật khó hiểu làm thế nào người dùng sẽ được chuyển hướng sau khi trả về _login (). Ví dụ thứ hai của bạn mặc dù có vẻ thuận tiện hơn. Nướng tốt.
aziza

1
Vâng, Hộp thoại có chức năng và yêu cầu sửa đổi rất ít đối với mã gốc của nó. Ví dụ, anh ta có thể theo dõi hộp thoại đóng bằng a Navigator.pushNamed("/home").
Rémi Rousselet

38

Đối với tôi, một cách đơn giản để làm điều này là hiển thị một SnackBarở dưới cùng trong khi quá trình Đăng nhập được diễn ra, đây là một ví dụ về ý tôi muốn nói:

nhập mô tả hình ảnh ở đây

Đây là cách thiết lập SnackBar .

Xác định khóa chung cho Scaffold

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

Thêm nó vào Scaffold keythuộc tính của bạn

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

Gọi onPressedlại nút Đăng nhập của tôi :

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")
                  );
                }

Nó thực sự phụ thuộc vào cách bạn muốn xây dựng bố cục của mình và tôi không chắc bạn nghĩ gì.

Biên tập

Có thể bạn muốn theo cách này, tôi đã sử dụng Ngăn xếp để đạt được kết quả này và chỉ hiển thị hoặc ẩn chỉ báo của tôi dựa trên onPressed

nhập mô tả hình ảnh ở đây

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,),

      ],));
  }

}

Xin chào, đó là những gì tôi muốn làm, nhưng tôi không có được bố cục mình cần. Stack là câu trả lời. Về StatefulWidget, có đúng là build all view khi trạng thái tiến trình thay đổi không?
Ricardo Bocchi

Này, tôi không hiểu câu hỏi của bạn?
aziza

Trong mã của tôi, khi _loadingthay đổi, tất cả các chế độ xem đều được xây dựng lại. Là vậy sao?
Ricardo Bocchi

1
Sử dụng một phương thức có lẽ dễ dàng hơn và trực quan hơn nhiều. Bạn chỉ có thể đẩy một hộp thoại đang tải theo yêu cầu hoặc yêu cầu của bạn và bật nó khi hoàn tất. Nó cũng có lợi thế là ngăn người dùng nhập thêm.
Rémi Rousselet

2
Okey, để tôi nướng cái gì đó.
Rémi Rousselet

34

Tạo bool isLoadingvà đặt nó thành false. Với sự trợ giúp của toán tử bậc ba, Khi người dùng nhấp vào nút đăng nhập, thiết lập trạng thái isLoadingthành true. Bạn sẽ nhận được chỉ báo tải hình tròn thay cho nút đăng nhập

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

Bạn có thể xem Ảnh chụp màn hình trông như thế nào trước khi nhấp vào đăng nhập nhập mô tả hình ảnh ở đây

Sau khi đăng nhập được nhấp vào nhập mô tả hình ảnh ở đây

Trong thời gian có nghĩa là bạn có thể chạy quá trình đăng nhập và người dùng đăng nhập. Nếu thông tin người dùng là sai sau đó một lần nữa bạn sẽ setStatecủa isLoadingđể false, như vậy mà chỉ tải sẽ trở thành invisible button và đăng nhập có thể nhìn thấy người dùng. Nhân tiện, primaryButton được sử dụng trong mã là nút tùy chỉnh của tôi. Bạn có thể làm tương tự với OnPressedtrong button.


Điều đó thực sự khá thông minh! Không cần phải xử lý nhấp đúp, vv Cảm ơn.
Benobab

Làm thế nào để xử lý nhấp đúp chuột trong tình huống này?

Tôi chưa bao giờ gặp tình huống đó để xử lý khi chạm hai lần vì khi chạm một lần, nó chuyển thành chỉ báo tải. Theo sự hiểu biết của tôi về nhận xét của bạn, tôi nghĩ chúng ta có thể bọc nút tùy chỉnh bằng bộ dò cử chỉ và sau đó bạn có thể làm việc bằng cách nhấn đúp vào đó.
Harsha pulikollu

Sử dụng toán tử bậc ba ở đâu? Ví dụ của bạn trông thông minh nhưng không chắc chắn về cách triển khai nó.
Bikram Pahi

Sử dụng đoạn mã được đề cập ở trên trong phương pháp tạo mà bạn muốn có nút (đăng nhập). Khi người dùng nhấp vào nút đó, bool (isLoading) trở thành true và hiển thị chỉ báo tải hình tròn thay vì nút.
Harsha pulikollu

20

1. Không có plugin

    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. Với plugin

kiểm tra plug-in này progress_hud

thêm phần phụ thuộc vào tệp pubspec.yaml

dev_dependencies:
  progress_hud: 

nhập gói

import 'package:progress_hud/progress_hud.dart';

Mã mẫu được đưa ra bên dưới để hiển thị và ẩn chỉ báo

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
Đừng bỏ phiếu cho điều này, một số người không muốn xử lý các chi tiết
phức tạp

3
thanh tiến trình trong api đủ công bằng khi thêm phụ thuộc sẽ tăng kích thước bản dựng. xây dựng đã rung là quá mức.
prashant0205,

Bạn có thực sự nên thêm điều này làm Phụ thuộc nhà phát triển không?
George

kiểm tra với ví dụ mới nhất pub.dartlang.org/packages/progress_hud#-example-tab-
Shyju M

1
@MohammadMeshkani sử dụng Navigator.pop (ngữ cảnh); trước khi chuyển sang màn hình tiếp theo
Shyju M

13

Bước 1: Tạo hộp thoại

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

Bước 2: Gọi nó

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

Ví dụ với Hộp thoại và biểu mẫu đăng nhập

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

nhập mô tả hình ảnh ở đây


2
Vui lòng thêm một chút ngữ cảnh vào câu trả lời của bạn.
Death Waltz

10

Tôi đã thực hiện cách tiếp cận sau, sử dụng tiện ích chỉ báo tiến trình phương thức đơn giản bao bọc bất cứ thứ gì bạn muốn thực hiện phương thức trong khi gọi không đồng bộ.

Ví dụ trong gói cũng đề cập đến cách xử lý xác thực biểu mẫu trong khi thực hiện các cuộc gọi không đồng bộ để xác thực biểu mẫu (xem flashing / issue / 9688 để biết chi tiết về vấn đề này). Ví dụ: mà không cần rời khỏi biểu mẫu, phương pháp xác thực biểu mẫu không đồng bộ này có thể được sử dụng để xác thực tên người dùng mới so với các tên hiện có trong cơ sở dữ liệu khi đăng ký.

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

Đây là bản demo của ví dụ được cung cấp với gói (có mã nguồn):

xác thực biểu mẫu không đồng bộ với chỉ báo tiến trình phương thức

Ví dụ có thể được điều chỉnh cho phù hợp với hành vi chỉ báo tiến độ theo phương thức khác (như các hoạt ảnh khác nhau, văn bản bổ sung trong phương thức, v.v.).


2

Đây là giải pháp của tôi với ngăn xếp

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

Tôi khuyên bạn nên sử dụng plugin này flay_easyloading

Flutter_easyloading là tiện ích tải nhẹ và gọn gàng cho Ứng dụng Flutter, dễ sử dụng mà không cần ngữ cảnh, hỗ trợ iOS và Android

Thêm cái này vào pubspec.yamltệp gói của bạn :

dependencies:
  flutter_easyloading: ^2.0.0

Bây giờ trong mã Dart của bạn, bạn có thể sử dụng:

import 'package:flutter_easyloading/flutter_easyloading.dart';

Để sử dụng Đầu tiên, hãy khởi tạo FlutterEasyLoadingtrong 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();
}

Sau đó, sử dụng theo yêu cầu của bạn

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

nhập mô tả hình ảnh ở đây


Lớp hoạt hình tùy chỉnh ở đâu? Chúng ta có cần phải bao gồm nó không.
Nayas Subramanian

Không, bạn không cần điều đó, và nếu bạn muốn thì hãy truy cập: github.com/huangjianke/flutter_easyloading/blob/develop/example/…
Paresh Mangukiya

1

Bạn có thể sử dụng tiện ích FutureBuilder để thay thế. Điều này nhận một đối số phải là Tương lai. Sau đó, bạn có thể sử dụng một ảnh chụp nhanh là trạng thái tại thời điểm của lệnh gọi không đồng bộ khi đăng nhập, khi nó kết thúc, trạng thái trả về của hàm không đồng bộ sẽ được cập nhật và trình tạo trong tương lai sẽ tự xây dựng lại để bạn có thể yêu cầu tiểu bang.

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

Ở đây bạn có một ví dụ về cách xây dựng Tương lai

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

1

Bạn có thể làm điều đó cho chỉ báo tiến trình minh bạch của trung tâm

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))),
                          ),
                        ),
                      ),

Làm cách nào để kết hợp một lớp tạo chỉ báo tải với nút của tôi, để khi tôi nhấn vào nó, chỉ báo sẽ bật và lật sang trang tiếp theo?
Max Zubko

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()));
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.