先看效果图如下:
在Flutter中,万物皆widget。所以这所谓的弹框其实也是一个widget。
而现实弹框其实就是打开一个新的路由,只不过背景颜色设为透明色就行了。
实现代码如下:
class LoadingDialog extends Dialog {
@override
Widget build(BuildContext context) {
return Center(
child: new Material(
///背景透明
color: Colors.transparent,
///保证控件居中效果
child: new Center(
///弹框大小
child: new SizedBox(
width: 120.0,
height: 120.0,
child: new Container(
///弹框背景和圆角
decoration: ShapeDecoration(
color: Color(0xffffffff),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
"加载中",
style: new TextStyle(fontSize: 16.0),
),
),
],
),
),
),
),
),
);
}
}
在flutter中,弹出loading只需要打开一个新的路由就行了
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return LoadingDialog ();
}));
运行效果如下:
可以发现,并没有半透明的背景
我们知道,在Android中,设置Activity半透明背景的时候,不仅需要在布局文件中设置背景色,还需要设置Activity的主题。
Flutter中其实也差不多,不仅需要设置Widget的背景颜色,还需要设置路由的barrierColor。
而设置barrierColor方式有两种:
Color get barrierColor => Colors.black54;
,给barrierColor 设置一个需要的背景色PageRouteBuilder
,当然了PageRouteBuilder
也继承自PageRoute我这里直接使用的PageRouteBuilder
。
代码如下:
class DialogRouter extends PageRouteBuilder{
final Widget page;
DialogRouter(this.page)
: super(
opaque: false,
barrierColor: Colors.black54,
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionsBuilder: (context, animation, secondaryAnimation, child) => child,
);
}
启动半透明路由:
Navigator.push(context, DialogRouter(LoadingDialog()));
这样就可以实现半透明效果了。
实现点击背景退出,只需要个背景添加一个点击事件就行了。
完整代码如下:
class LoadingDialog extends Dialog {
LoadingDialog(this.canceledOnTouchOutside) : super();
///点击背景是否能够退出
final bool canceledOnTouchOutside;
@override
Widget build(BuildContext context) {
return Center(
child: new Material(
///背景透明
color: Colors.transparent,
///保证控件居中效果
child: Stack(
children: [
GestureDetector(
///点击事件
onTap: (){
if(canceledOnTouchOutside){
Navigator.pop(context);
}
},
),
_dialog()
],
)
),
);
}
Widget _dialog(){
return new Center(
///弹框大小
child: new SizedBox(
width: 120.0,
height: 120.0,
child: new Container(
///弹框背景和圆角
decoration: ShapeDecoration(
color: Color(0xffffffff),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
"加载中",
style: new TextStyle(fontSize: 16.0),
),
),
],
),
),
),
);
}
}