Flutter之Dialog 对话框各种用法

前言:

各位同学大家好 ,相信移动端(安卓, iOS )和前端的同学都有使用过dialog对话框 ,移动端(安卓 iOS )和前端 对于diaog 的实现 都有很好用的对应的原生api支持, 网上也有很多开源博客 我这边就不展开详细讲了,今天给大家分享一下flutter中dialog对话框的各种用法 。

准备工作:

安装flutter环境 如果只是跑安卓设备 win系统就行了 要是同时运行安卓和iOS 就需要mac电脑了 配置环境变量这边就不展开讲了大家可以看我之前的文章

需要用到的三方库

fluttertoast: ^3.1.3 toast 库

效果图

alertDialog:

QQ截图20200531131836.png

simpleDialog:

QQ截图20200531131903.png
QQ截图20200531131851.png
QQ截图20200531131911.png

modeBottomDialog:

QQ截图20200531131929.png

toastDialog:

QQ截图20200531131945.png

自定义LoadingDialog (网络加载) :

QQ截图20200531132014.png

具体代码实现:

alertDialog:

alertDialog警报对话框会通知用户需要确认的情况。警报对话框具有可选标题和可选的操作列表。标题显示在内容上方,操作显示在内容下方。通常我们在点击一些需要用户确认操作的功能(例如删除,等 )的时候就会用到这个alertDialog 警报对话框。

如图:

QQ截图20200531131836.png

alertDialog的代码实现 :

  Future  _alertDialog()async{
    var  result  =await showDialog(
        context: context,
        builder: (context){
          return  AlertDialog(
            title: Text("提示信息"),
            content: Text("您确定要删除吗"),
            actions: <Widget>[
              RaisedButton(
                child: Text("取消"),
                color: Colors.blue,
                textColor: Colors.white,
                onPressed: (){
                  print("取消");
                  Toast.show("你取消了", context);
                  Navigator.pop(context);
                },
              ),
              RaisedButton(
                child: Text("确定"),
                color: Colors.blue,
                textColor: Colors.white,
                onPressed: (){
                  print("确定");
                  Toast.show("你确定了", context);
                  Navigator.pop(context,"ok");
                },
              ),
            ],
          );
        }
    );
    print("result   -- >  "+result);
  return  result;
  }

这边我们定义了_alertDialog 方法 然后在里面调用了showDialog()组件 返回一个 AlertDialog()组件
AlertDialog()组件中我们设置 title 和content , 然后 actions 属性中插入 两个RaisedButton 来处理对话框里点击的操作, 通过调用Navigator.pop(context); 来处理 对话框架 点击销毁 以及点击拿的结果 最我们将选择项点击的操的结果赋值给 var result 变量并返回 。

具体 _alertDialog ()方法的调用

  Widget build(BuildContext context) {
    // TODO: implement build
    return  Scaffold(
      appBar: AppBar(
        title: Text("alertDialog弹出演示"),
      ),
      body: Container(
        child: RaisedButton(
          child: Text(
              "点击显示alertDialog"
          ),
          onPressed: (){
            _alertDialog().then((value){
              print(value);
            });
          },
        ),
      ),
    );
  }

simpleDialog:

简单的对话框为用户提供了多个选项之间的选择。一个简单的对话框有一个可选的标题,显示在选项上方。下面则是具体的选择项 ,通常我们在项目中用这个simpleDialog 来实现一些列表选择则的功能的实现 。

如图:

QQ截图20200531131903.png
QQ截图20200531131851.png
QQ截图20200531131911.png

simpleDialog的代码实现 :

 Future  simpleDialog()async{
    var  result=await showDialog(context: context,
        builder:(context){
          return SimpleDialog(
            title: Text("选择角色"),
            children: <Widget>[
              SimpleDialogOption(
                child: Text("旋涡名人"),
                onPressed: (){
                  print("旋涡名人");
                  Navigator.pop(context,"旋涡名人");
                },
              ),
              SimpleDialogOption(
                child: Text("宇智波佐助 "),
                onPressed: (){
                  print("宇智波佐助");
                  Navigator.pop(context,"宇智波佐助");
                },
              ),
              SimpleDialogOption(
                child: Text("千手柱间"),
                onPressed: (){
                  print("千手柱间");
                  Navigator.pop(context,"千手柱间");
                },
              ),
              SimpleDialogOption(
                child: Text("宇智波斑"),
                onPressed: (){
                  print("宇智波斑");
                  Navigator.pop(context,"宇智波斑");
                },
              ),
            ],
          );
        }
    );
    print("result --- > "+result);
    return result;
  }

这边我们定义了simpleDialog方法 然后在里面调用了showDialog()组件 返回一个 SimpleDialog()组件
SimpleDialog()组件中我们设置 title , 然后通过 children属性中插入 多个SimpleDialogOption来处理对话框里面的选择项的操作 通过调用Navigator.pop(context); 来处理 对话框架 点击销毁 以及点击拿的结果 最我们将选择项点击的操的结果赋值给 var result 变量并返回

具体调用:

@override
Widget build(BuildContext context) {
  // TODO: implement build
  return Scaffold(
    appBar: AppBar(
      title: Text("simpleDialog "),

    ),
    body: Container(
      color: Colors.white,
      child: Center(
        child: RaisedButton(
          child: Text(textStr),
          onPressed:(){
            simpleDialog().then((value){
              setState(() {
                if(!textStr.isEmpty){
                  textStr=value;
                }
              });
            });
          } ,
        ),
      ),
    ),
  );
}

通过调用 simpleDialog方法的 then属性拿到返回的结果 然后赋值给我们点击的RaisedButton 的Text 里面的变量

  onPressed:(){
       simpleDialog().then((value){
          setState(() {
              if(!textStr.isEmpty){
                 textStr=value;
                  }
            });
         });
   }

modeBottomDialog:

modeBOttomDialog 通常我用来实现一键分享的功能的实现 (如分享到微信 微博 QQ等 )

如图:

QQ截图20200531145448.png

具体代码实现:

  Future   _modeBottomDialog()async{
    var  result=await showModalBottomSheet(context: context,
        builder: (context){
          return Container(
            child: Column(
              children: <Widget>[
                ListTile(
                    title: Text("分享到 QQ"),
                    onTap: (){
                      Navigator.pop(context,"分享到 QQ");
                    }
                ),
                ListTile(
                    title: Text("分享到 微信 "),
                    onTap: (){
                      Navigator.pop(context,"分享到 微信");
                    }
                ),
                ListTile(
                    title: Text("分享到 微博"),
                    onTap: (){
                      Navigator.pop(context,"分享到 微博");
                    }
                ),
                ListTile(
                    title: Text("分享到 知乎"),
                    onTap: (){
                      Navigator.pop(context,"分享到 知乎");
                    }
                ),
              ],
            ),
          );
        }
    );
    print("分享 --- > "+result);
   return result;
  }

这边我们定义了_modeBottomDialog方法 然后在里面调用了showModalBottomSheet()组件, 传入context 上下文返回一个 widget。(widget 你想要返回 什么样看你自己发挥 这我返回一个 Container 里面包裹一个 Column)然后我们再Column 的 children 里面插入多条ListTitle 来显示分享的点击条目,同simple 一样通过调用Navigator.pop(context,"分享到 知乎"); 来处理 对话框架 点击销毁 以及点击拿的结果 最我们将选择项点击的操的结果赋值给 var result 变量并返回。

具体调用:

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("modeBOttomDialog"),
      ),
      body: Container(
        child: RaisedButton(
          child: Text("分享"
          ),
          onPressed: (){
            _modeBottomDialog().then((value){
              print("value    ---  > "+value  );
            });
          },
        ),
      ),
    );
  }

toastDialog:

toastDialog 是平时用来做提示的 toast 信息实现 (例如, 账号密码不能为空 ,账号或者密码不对 )
toastDialog 这个需要用到三方库 fluttertoast: ^3.1.3 我们先要在 pubspec.yaml 中添加依赖

QQ截图20200531153402.png

然后执行 在控制台 执行flutter pub get 下载依赖
使用需要导入这个包

import 'package:fluttertoast/fluttertoast.dart';

toastDialog具体代码实现 :

_toast()async{
    Fluttertoast.showToast(
        msg: "This is Center Short Toast",  //弹出内容
        toastLength: Toast.LENGTH_SHORT, //弹出时间长短 
        gravity: ToastGravity.CENTER, //弹出位置  上 下  中   
        timeInSecForIos: 3,  //在什么平台上面使用  安卓  IOS  Web
        backgroundColor: Colors.black, // 背景颜色
        textColor: Colors.white, //字体颜色
        fontSize: 16.0 //字体大小 
    );

我们调用三方库里面的 showToast ()组件反别设置

        msg: "This is Center Short Toast",  //弹出内容
        toastLength: Toast.LENGTH_SHORT, //弹出时间长短 
        gravity: ToastGravity.CENTER, //弹出位置  上 下  中   
        timeInSecForIos: 3,  //在什么平台上面使用  安卓  IOS  Web
        backgroundColor: Colors.black, // 背景颜色
        textColor: Colors.white, //字体颜色
        fontSize: 16.0 //字体大小 

各个属性来满足我们实际需求

具体调用:

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
         title: Text("_toastDialogState"),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text("点击弹出toast"),
              onPressed: _toast,
            ),
            RaisedButton(
              child: Text("调用封装的方法弹出"),
              onPressed:  ()async{
                ToastUtil.showInfo("显示toast");
              },
            )
          ],
        )
      ),
    );
  }

我们也可以对toast进行适当的封装

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

class   ToastUtil{
   static  void   showInfo(String  str)async {
     Fluttertoast.showToast(
         msg: str,
         toastLength: Toast.LENGTH_SHORT,
         gravity: ToastGravity.CENTER,
         timeInSecForIos: 3,
         backgroundColor: Colors.black,
         textColor: Colors.white,
         fontSize: 16.0
     );
   }
}

然后再其他类只需要导入我这个工具类就行了
直接调用:

    RaisedButton(
              child: Text("调用封装的方法弹出"),
              onPressed:  ()async{
                ToastUtil.showInfo("显示toast");
              },
     )

自定义 LoadingDialog(网络加载对话框):

通常我们再加载网络 请求后台的数据展示再我们的app上面的时候 这个过程需要一定的时间
所以这个时候我们需要做一个loadingDialog 页面来处理 这个等待的过程

如图:

QQ截图20200531132014.png

具体代码实现:

import 'package:flutter/material.dart';
class LoadingDialog extends Dialog {
  String text;
  LoadingDialog({Key key, @required this.text}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return new Material(
      //创建透明层
      type: MaterialType.transparency, //透明类型
      child: new Center(
        //保证控件居中效果
        child: new SizedBox(
          width: 100.0,
          height: 100.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(
                    text,
                    style: new TextStyle(fontSize: 12.0),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

这里我们自己创建一个loadingDialog 需要继承flutter sdk 里面的Dialog 然后重写 build 方法 需要返回一个widget
我们这里返回Material 来设置透明效果 然后再里面嵌套 Center 来使得我们的要展示的内容居中显示
然后创建 Sizebox 盒子模型组件 设置宽高 各100的正方形 来装载我们显示的的内容
我们通过 ShapeDecoration 组件来实现 loading 动画效果
在下面我们加一个text显示我们需要显示的提示的文字 (加载中 等待中 等等 )

具体调用 :

我们需要写一个 showCustomDialog 方法来转载我们的loadingDialog

  void showCustomDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return LoadingDialog(text: "加载中");
        });
  }

然后我们在具体的业务逻辑中的widget 或者网络请求中调用

import 'package:flutter/material.dart';
import '../dialog/loading_dialog.dart';

class LoagingWidget extends StatefulWidget {
  LoagingWidget({Key key}) : super(key: key);

  @override
  _LoagingWidgetState createState() {
    return _LoagingWidgetState();
  }
}

class _LoagingWidgetState extends State<LoagingWidget> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return  Scaffold(
      appBar: AppBar(
        title: Text("网络加载loading"),

      ),
      body: Container(
        child: RaisedButton(
          child: Text("点击加载"),
          onPressed: (){
            setState(() {
              showCustomDialog(context);
            });
          },
        ),
      ),
    );
  }
  void showCustomDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return LoadingDialog(text: "加载中");
        });
  }
}

关闭对话框 通过调用 Navigator.pop(context) 来关闭

Navigator.pop(context);

到此flutter 中dialog 的各种用法就介绍完了 如果有错误或者遗漏的地方希望各位同学及时指正
项目地址:https://github.com/xq19930522/flutter_dialog_demo.git

最后总结 :

flutter中的dialog提供的api比较丰富 例如 alertDialog simpleDialog modeBottomDialog toastDialog
这些都可以实现很多功能的需求 这些dialog我们都可以自己自定义dialog 继承flutter sdk里面的Dialog来实现的 有兴趣的同学可以自己在私下研究 这里就不过多讲了 最后希望我的文章能帮助到各位解决问题,各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272