Flutter之网络请求过渡动画--LoadingDialog

2月27日更新

  今日又用到了我自己写的 loadDialog,才发现以前的写法是如此的简陋。现在我想到了另外一个方法。关于 如何在 A 页面执行的方法中来关闭 弹出的 Dialog。

主要用到了 回调

代码如下:
import 'dart:async';

import 'package:flutter/material.dart';

// ignore: must_be_immutable
class NetLoadingDialog extends StatefulWidget {
  String loadingText;
  bool outsideDismiss;

  Function dismissDialog;

  NetLoadingDialog(
      {Key key,
      this.loadingText = "loading...",
      this.outsideDismiss = true,
      this.dismissDialog})
      : super(key: key);

  @override
  State<NetLoadingDialog> createState() => _LoadingDialog();
}

class _LoadingDialog extends State<NetLoadingDialog> {
  _dismissDialog() {
    Navigator.of(context).pop();
  }

  @override
  void initState() {
    super.initState();
    if (widget.dismissDialog != null) {
      widget.dismissDialog(

          //将关闭 dialog的方法传递到调用的页面.
          (){Navigator.of(context).pop();}

      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return xxxx
    }
}

build方法不变,主要在于利用了 dismissDialog ,向调用这个界面的地方 回传了一个 pop 方法,这样 只要在自己处理完的地方调用即可。

调用代码:

showDialog(
          context: context,
          builder: (context) {
            return new NetLoadingDialog(
              dismissDialog: _disMissCallBack,
              outsideDismiss: false,
            );
          }
      );


  //这个func 就是关闭Dialog的方法,在适当的时候关闭即可
  _disMissCallBack(Function func) {
       xxx
      showSnackBar("登录成功");
      func();
   }

这样,很多情况下都可以用 回调 的方式来处理了 ,over。

与我第一次写的相比,主要是将 逻辑置于自己的页面来处理了,各有各的利用情况。
希望都能给你些灵感。


以下是原文


  今天再分享一下Flutter网络加载的过渡动画,因为刚好前面写了自定义 Dialog 以及网络请求,现在结合一下。
1、先上效果图
2、说一下实现思路

  因为新打开的Dialog是另外一个界面了,所以我想,如果用pop(context),那么就必须获取到dialog的contex,那么为啥不让dialog自己调用关闭自己呢。所以我实现了如下Dialog:

import 'dart:async';
import 'package:flutter/material.dart';

// ignore: must_be_immutable
class NetLoadingDialog extends StatefulWidget {
  String loadingText;
  bool outsideDismiss;
  Function dismissCallback;
  Future<dynamic> requestCallBack;

  NetLoadingDialog(
      {Key key,
      this.loadingText = "loading...",
      this.outsideDismiss = true,
      this.dismissCallback,
      this.requestCallBack})
      : super(key: key);

  @override
  State<NetLoadingDialog> createState() => _LoadingDialog();
}

class _LoadingDialog extends State<NetLoadingDialog> {
  _dismissDialog() {
    if (widget.dismissCallback != null) {
      widget.dismissCallback();
    }
    Navigator.of(context).pop();
  }

  @override
  void initState() {
    super.initState();
    if (widget.requestCallBack != null) {
      widget.requestCallBack.then((_) {
        Navigator.pop(context);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: widget.outsideDismiss ? _dismissDialog : null,
      child: Material(
        type: MaterialType.transparency,
        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(
                      widget.loadingText,
                      style: new TextStyle(fontSize: 12.0),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

这里主要传递了一个requestCallBack的Future函数,然后在initState中监听返回,当执行完成的时候,关闭dialog。所以,主要就是传递一个Future函数给Dialog,这也是为啥我上篇网络请求返回Future的原因。

使用起来就简单了,和普通的Dialog一样。

3、How to Use
showDialog(
        context: context,
        barrierDismissible: false,
        builder: (_) {
          return new NetLoadingDialog(
            requestCallBack: _register(),
            outsideDismiss: false,
          );
        });

而这个_register()方法就是一个Future函数。

4、其它实现方式

  可以自己先写一个Loading 的界面,然后在需要调用的时候,根据state来判断,是否加载loading界面,当然咯,这个loading界面也可以设置成半透明的。

  @override
  Widget build(BuildContext context) {
    if(showLoading){
      return xxx;
    }
 }

这里外层可以使用Stack布局,像Android里面的FrameLayout。这样就能把两个布局"重合"在一起。实现展示Loading的能力。同样的,改变状态就需要调用setState即可。当然前提是这得是一个StatefulWidget。

  ok,有其它的方式后再补充,或者如果有更好的方式,能在A页面中关闭A页面打开的Dialog,希望您能评论告诉我。
  希望我的方法对你有帮助。

Github 地址

你可能感兴趣的:(Flutter)