在Flutter中的前面显示CircularProgressIndicator

时间:2020-05-01 06:51:17

标签: flutter dart

我想在其他小部件前面显示一个类似加载的圆条。 以下是我当前正在使用的代码。它显示了循环加载,但显示在其他小部件之间。

它应该在顶部。根据建议,我尝试使用Stack,但仍显示在小部件之间。我在这里做什么错了?

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();

}

class _LoginPageState extends State<LoginPage> {

 bool visible = true ; //Testing purpose it is true. Actually it is false.    
@override

Widget build(BuildContext context) {

return Scaffold(
  key: _scaffoldKey,
  body: Stack(
        children: <Widget>[
          new Container(
            decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topRight,
              end: FractionalOffset.bottomCenter,//Alignment.bottomLeft,

              colors: [Colors.green[900], Colors.lightBlueAccent]),
        ),

          ),SingleChildScrollView(
            child: new Form(
              key: _formKey,
              autovalidate: _autoValidate,
    child: Center(
    child: Column(
      children: <Widget>[
        Row(
                  children: <Widget>[
                    VerticalText(),
                    TextLogin(),                    
                  ],
                ),


        Divider(),          

        Container(
        width: 280,

        ),
        Container(
        width: 280,
        child: TextFormField(
          style: TextStyle(
            color: Colors.white,
          ),
            decoration: InputDecoration(
            border: InputBorder.none,
            hintText: 'Enter Email',
            fillColor: Colors.lightBlueAccent,
            labelText: 'Email',
            labelStyle: TextStyle(
              color: Colors.white70,
              fontSize: 20,
            ),
            ),
            controller: emailController,
            autocorrect: true,
            validator: validateEmail,
            onSaved: (String val) {
              _email = val;
          },
          )
        ),

        Container(
        width: 280,
        child: TextFormField(
             style: TextStyle(
            color: Colors.white,
          ),
            decoration: InputDecoration(
            border: InputBorder.none,
            hintText: 'Enter Password',
            fillColor: Colors.lightBlueAccent,
            labelText: 'Password',
            labelStyle: TextStyle(
              color: Colors.white70,
              fontSize: 20,
            ),
            ),
            controller: passwordController,
            autocorrect: true,
            obscureText: true,
            validator: validatePassword,
              onSaved: (String val) {
                _password = val;
          },
          )
        ),

        RaisedButton(
          onPressed: _validateInputs,
          color: Colors.green,
          textColor: Colors.white,
          padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
          child: Text('Login'),
        ),


        Visibility(
          child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                child: CircularProgressIndicator(
                  strokeWidth: 4.0,
                  valueColor : AlwaysStoppedAnimation(Colors.white),
                ),
                height: 200.0,
                width: 200.0,
              ),

            ],
          ),
        ),
          visible: visible, 
      ),
      ],
    ),
  )
            )
  )
        ],
),
);
}

我在SO中也看到过类似的问题,但仍然很难解决。

How to work with progress indicator in flutter?

flutter how to get a circular progress indicator working

Flutter : create an overlay progress bar

How to display CircularProgressIndicator on top of all widget in a centre of the screen

5 个答案:

答案 0 :(得分:5)

circularProgressIndicator的真正含义是在加载过程中运行而不会让用户中断。
要消除用户之间的干扰,应将circularProgressIndicator放在属性为barrierDismissible: false的对话框中。
应该将这个加载指示器创建为可重用的小部件。
您可以创建如下所示的方法,并且可以在屏幕上的任何位置使用它,而无需在屏幕上进行定义。 (这也不需要堆栈。)。对话框将出现在屏幕中央。

buildShowDialog(BuildContext context) {
    return showDialog(
              context: context,
              barrierDismissible: false,
              builder: (BuildContext context) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              });
  }

供参考:以下结帐代码:

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Demo(),
    );
  }
}

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Circle Progress Indicator Demo"),
      ),
      body: Center(
        child: MaterialButton(
          child: Text("Press Me!"),
          onPressed: () => buildShowDialog(context),
        ),
      ),
    );
  }

  buildShowDialog(BuildContext context) {
    return showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return Center(
            child: CircularProgressIndicator(),
          );
        });
  }
}

输出:
enter image description here

答案 1 :(得分:1)

您可以在Positioned窗口小部件中使用Stack窗口小部件,以便在如下所示的所有窗口小部件前面显示CircularProgressIndicator
请根据您的方便在所有四个值的底部,左侧,右侧,顶部...中放置值。

         Positioned(
                bottom: ,
                left: ,
                right: , 
                top : ,
                child: Container(
                        child : CircularProgressIndicator()
                      )
                    ...
                   )

答案 2 :(得分:0)

我与此代码一起删除了Visiblity代码。 旧代码

 Visibility(

          child: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                child: CircularProgressIndicator(
                  strokeWidth: 4.0,
                  valueColor : AlwaysStoppedAnimation(Colors.white),
                ),
                height: 200.0,
                width: 200.0,
              ),


            ],
          ),
        ),
          visible: visible, 
      ), 

新代码

 visible ? Container(
                        color: Colors.black.withOpacity(0.5),
                        child:  Center(
                        child:SizedBox(// Center(

                          child: CircularProgressIndicator(
                            strokeWidth: 4.0,
                      valueColor : AlwaysStoppedAnimation(Colors.white),
                          ),
                          height: 200.0,
                          width: 200.0,
                        ),
                       ), 
    )
                      : Container()

最重要的是,它需要在第一个Widget中调用。

    return Scaffold(
      key: _scaffoldKey,
      body: Stack(
            children: <Widget>[
/////Some containers,child Widget etc/////////
     visible ? Container(
                            color: Colors.black.withOpacity(0.5),
                            child:  Center(
                            child:SizedBox(// Center(

                              child: CircularProgressIndicator(
                                strokeWidth: 4.0,
                          valueColor : AlwaysStoppedAnimation(Colors.white),
                              ),
                              height: 200.0,
                              width: 200.0,
                            ),
                           ), 
        )
                          : Container()

] //Widget
  ), //Stack
); //Scaffold

我不确定我是否正确解释了。但最重要的是,它不应位于其他子小部件内。 应该将其放在第一个children: <Widget>[内部,而不是嵌套内部。

答案 3 :(得分:0)

对于任何想在任何地方使用LoadingIndicator flexible并希望覆盖当前屏幕的人,只需制作一个包含以下内容的.dart文件:

import 'package:flutter/material.dart';

buildLoading(BuildContext context) {
  return showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return Center(
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
          ),
        );
      });
}

然后您可以在任何地方使用它

buildLoading(context);

,并在使用完成加载后将其关闭

Navigator.of(context).pop();

答案 4 :(得分:0)

如上所述,他们中的大多数人都给出了单独的可重用功能的答案。所以如果你想获取一些数据并在获取数据时显示循环进度指示器,这里是我的。

///Function to get data from a future and display a dialog with circlular progress indicator while data is fetched.
getFutureData(BuildContext context, var future) async {
  var data;
  await showDialog(
    context: context,
    barrierDismissible: false,
    builder: (context) => Center(
      child: FutureBuilder(
        future: future,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            data = snapshot.data;
            Navigator.pop(context);
          }
          return CircularProgressIndicator();
        },
      ),
    ),
  );
  return data;
}