我想在其他小部件前面显示一个类似加载的圆条。 以下是我当前正在使用的代码。它显示了循环加载,但显示在其他小部件之间。
它应该在顶部。根据建议,我尝试使用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
答案 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(),
);
});
}
}
答案 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;
}