自定义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),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
发布了82 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/sjdjdjdjahd/article/details/101620425