先看效果圖如下:
在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: <Widget>[
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
"加載中",
style: new TextStyle(fontSize: 16.0),
),
),
],
),
),
),
),
),
);
}
}
彈出loading
在flutter中,彈出loading只需要打開一個新的路由就行了
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return LoadingDialog ();
}));
運行效果如下:
可以發現,並沒有半透明的背景
實現半透明背景
我們知道,在Android中,設置Activity半透明背景的時候,不僅需要在佈局文件中設置背景色,還需要設置Activity的主題。
Flutter中其實也差不多,不僅需要設置Widget的背景顏色,還需要設置路由的barrierColor。
而設置barrierColor方式有兩種:
- 繼承PageRoute自己實現一個路由,重寫
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: <Widget>[
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: <Widget>[
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
"加載中",
style: new TextStyle(fontSize: 16.0),
),
),
],
),
),
),
);
}
}