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
Widgetbuild(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,希望您能评论告诉我。
  希望我的方法对你有帮助。