flutter - 如何在 flutter 中使用进度指示器?

我是 Flutter 的新手,想知道在我的布局中添加 CircularProgressIndicator 的更好方法。例如,我的登录 View 。这个 View 有用户名、密码和登录按钮。我确实想创建一个覆盖布局(使用 Opacity),在加载时显示进度指示器,就像我在 NativeScript 中使用的那样,但我对如何做以及如果它是更好的方法有点困惑.例如,在 NativeScript 上,我在主布局中添加了 IndicatorActivity 并将 busy 设置为 true 或 false,因此在加载时它会覆盖所有 View 组件。

编辑:

我能够达到这个结果:

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

我还在适应状态的想法。使用 flutter 时,此代码在预期范围内吗?

谢谢!

最佳答案

在 Flutter 中,有几种处理异步 Action 的方法。

一种懒惰的方法是使用模式。这将阻止用户输入,从而防止任何不需要的操作。 这将需要对您的代码进行很少的更改。只需修改您的_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),
          );
        }
      },
    );
  }
}

https://stackoverflow.com/questions/47065098/

相关文章:

flutter - InkWell 没有显示涟漪效应

flutter - 更改项目名称

flutter - 有多个英雄在子树中共享相同的标签

functional-programming - Dart:映射列表(list.map)

flutter - 如何在 flutter 中为文本加下划线

flutter - 在 Flutter 中延迟一段时间后如何运行代码?

dart - 如何将非字符串数据传递给 Flutter 中的命名路由?

flutter - 如何根据父级的大小布局小部件?

flutter - 如何获取 Widget 的高度?

git - flutter 安装期间的libusbmuxd版本错误