自定義Flutter loading彈框

先看效果圖如下:
在這裏插入圖片描述
在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),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章