美文网首页Flutter知识库
Flutter第十一章(AlertDialog ,Simple

Flutter第十一章(AlertDialog ,Simple

作者: 一巴掌拍出两坨脂肪 | 来源:发表于2021-04-28 14:58 被阅读0次
    版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!

    情感语录: 今日的事情,尽心、尽意、尽力去做了,无论成绩如何,都应该高高兴兴地上床恬睡。

    欢迎来到本章节,上一章节介绍了常用可滚动组件的使用,知识点回顾 戳这里 Flutter基础第十章

    本章简要:

    1、AlertDialog 对话框

    2、SimpleDialog 对话框

    3、showModalBottomSheet 底部弹框

    4、CupertionDialogAction IOS风格对话框

    5、LinearProgressIndicator 条形进度条

    6、CircularProgressIndicatorr 圆形进度条

    7、自定义对话框和进度条实现加载 Dialog 效果

    前景提要: 为了不赘述,这里 说明下在 Flutter 中 要弹出对话框需要 在 showDialog()函数中处理,且它是一个异步的,如果要接收对话框里的返回值 可以通过 Dart 中讲解的 async 和 await 来处理接收值,也可以使用 Flutter 中提供的 then() 接收一个异步的回调函数,可以在这里面处理接收值。 Dialog的关闭 使用Navigator.pop(context);或者 Navigator.pop(context,"传值");

       Future<T> showDialog<T>({
          @required BuildContext context,
          bool barrierDismissible = true,
          @Deprecated(
          ) Widget child,
          WidgetBuilder builder,
        })
    

    context : 必传参数上下文。

    barrierDismissible: 点击其他区域是否能关闭对话框。

    child : 指各种类型的对话框。

    一、AlertDialog 对话框

    像 Android 原生中 AlertDialog 一样,它可以实现一个提示对话题 ,但它的使用比原生更加方便灵活。

    构造函数:

      const AlertDialog({
        Key key,
        this.title,
        this.titlePadding,
        this.titleTextStyle,
        this.content,
        this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
        this.contentTextStyle,
        this.actions,
        this.backgroundColor,
        this.elevation,
        this.semanticLabel,
        this.shape,
      }) 
    
    常用属性:
        属性                           描述
    
        title                         对话框标题
    
        titlePadding                  标题的内距
    
        titleTextStyle                标题文字样式
    
        content                       对话框内容
    
        contentPadding                话框内容内距
    
        contentTextStyle              话框内容样式
    
        actions                       一般放 确定 取消按钮组
         
        backgroundColor               对话框背景色
    
        elevation                     设置阴影(视乎没效果)
    
        shape                         设置Dialog 形状,如圆角
    

    简单运用:

      import 'package:flutter/material.dart';
      import 'package:flutter_learn/util/ToastUtil.dart';
    
      class DialogPage extends StatefulWidget {
        DialogPage({Key key}) : super(key: key);
    
        _DialogPageState createState() => _DialogPageState();
      }
    
      class _DialogPageState extends State<DialogPage> {
    
        _alertDialog() {
    
          showDialog(
             //表示点击灰色背景的时候是否消失弹出框
              barrierDismissible:false,
              context:context,
              builder: (context){
                return AlertDialog(
                  //添加背景色
                  backgroundColor:Colors.white,
                  elevation: 1000,
                  // 文字内容内距
                  contentPadding:EdgeInsets.all(30) ,
                  //标题
                  title: Text("提示信息!",style: TextStyle(color: Colors.redAccent),),
                  //内容
                  content:Text("您确定要删除吗?"),
                  //控制圆角
                  shape:RoundedRectangleBorder(borderRadius:BorderRadius.all(Radius.circular(10))),
    
                  actions: <Widget>[
                    FlatButton(
                      child: Text("取消"),
                      onPressed: (){
                        Navigator.pop(context,'Cancle');
                      },
                    ),
                    FlatButton(
                      child: Text("确定"),
                      onPressed: (){
                        Navigator.pop(context,"Ok");
                      },
                    )
                  ],
                );
              }
          ).then((value){
            ToastUtil.show("回传值:"+value);
          });
        }
    

    效果如下:

    AlertDialog.gif

    是吧! 非常简单,这里使用了RoundedRectangleBorder 来控制 Dialog 进行了圆角样式, 在 Flutter 中还有很多 ShapeBorder 可以选择,更多用法请参阅内部源码。

    二、SimpleDialog 对话框

    SimpleDialog 用法与 AlertDialog 非常相似,SimpleDialog 常常结合 SimpleDialogOption 组件一起使用。

    构造函数:

      const SimpleDialog({
        Key key,
        this.title,
        this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
        this.children,
        this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),
        this.backgroundColor,
        this.elevation,
        this.semanticLabel,
        this.shape,
      })
    

    SimpleDialog 中的属性和 AlertDialog 几乎一致,需要注意的是 这里的 children 属性 接收的是一个List<Widget> 这意味着我们可以在这里面自定义各种各样的组件和样式。

    简单运用:

      _simpleDialog() async{
    
        var result= await  showDialog(
    
            barrierDismissible:false,
            context:context,
            builder: (context){
              return SimpleDialog(
                title:Text("选择内容",style: TextStyle(color: Colors.blue)),
                children: <Widget>[
    
                  SimpleDialogOption(
                    child: Text("Option A"),
                    onPressed: (){
                      Navigator.pop(context,"A");
                    },
                  ),
                  Divider(),
                  SimpleDialogOption(
                    child: Text("Option B"),
                    onPressed: (){
                      Navigator.pop(context,"B");
                    },
                  ),
                  Divider(),
                  SimpleDialogOption(
                    child: Text("Option C"),
                    onPressed: (){
                      Navigator.pop(context,"C");
                    },
                  ),
                  Divider(),
    
                ],
    
              );
            }
        );
    
        ToastUtil.show("回传值:"+result);
    
      }
    

    效果如下:

    SimpleDialog.gif

    从上面的两个案例中 无论是 async 和 await 还是 then () 接收回调函数都能正确拿到从 Dialog 中返回的值。在 Flutter 开发中尽量使用 then() 方式,因为它的链式调用能明确代码执行的依赖关系和实现异常捕获。

    三、showModalBottomSheet 底部弹出框

    showModalBottomSheet 属性和 AlertDialog 一致。它在开发中也是非常实用的,如:常见的底部弹出一个分享的弹出框,还有如上传头像是弹出的选择 照片或者相机的弹出框。下面来仿写一个分享弹框:

     _modelBottomSheet() {
    
        showModalBottomSheet(
            context: context,
            builder: (context) {
              return Container(
                color: Colors.white,
                height: 220,
                child: Column(
                  children: <Widget>[
                    Container(
                      height: 50,
                      child: Center(
                        child: Text(
                          "分享",
                          style: TextStyle(color: Colors.black54),
                        ),
                      ),
                    ),
                    Divider(),
                    Row(
                      mainAxisAlignment:MainAxisAlignment.center,
                      children: <Widget>[
    
                        Container(
                          width: 80,
                          color: Colors.white,
                          child: Column(children: <Widget>[
                            Icon(Icons.chat,color: Colors.green, size: 40,),
                            SizedBox(height: 10),
                            Text('微信', style: TextStyle(color: Colors.deepPurple)),
    
                          ],)
                        ),
    
                        Container(
                            width: 140,
                            color: Colors.white,
                            child: Column(children: <Widget>[
                              Icon(Icons.question_answer,color: Colors.green,size: 40,),
                              SizedBox(height: 10),
                              Text('QQ', style: TextStyle(color: Colors.deepPurple)),
    
                            ],)
                        ),
    
                        Container(
                            width: 80,
                            color: Colors.white,
                            child: Column(children: <Widget>[
                              Icon(Icons.web,color: Colors.green,size: 40,),
                              SizedBox(height: 10),
                              Text('微博', style: TextStyle(color: Colors.deepPurple)),
    
                            ],)
                        ),
                      ],
                    ),
    
                    SizedBox(height: 20),
    
                    FlatButton(
    
                      textColor: Colors.white,
                      disabledColor: Colors.grey,
                      disabledTextColor: Colors.grey,
                      color: Colors.blue,
                      highlightColor: Colors.blue[700],
                      colorBrightness: Brightness.dark,
                      splashColor: Colors.grey,
                      child: Text("取消"),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20.0)),
                      //按钮点击回调
                      onPressed: () =>  Navigator.pop(context)
                    ),
    
                  ],
    
                ),
              );
            });
      }
    

    效果如下:

    showModalBottomSheet.gif

    写的比较简单,图片也是随便用的系统的,但可以看出效果还是不错的 O(∩_∩)O

    四、CupertinoAlertDialog IOS 风格对话框

    CupertinoAlertDialog 和 AlertDialog 在使用上没有什么区别,需要注意的是 使用IOS 风格的 actions 时 也得使用 IOS 风格的 CupertinoDialogAction 组件。

       _showCupertinoAlertDialog() {
    
        showDialog(
            context: context,
            builder: (BuildContext context) {
              return CupertinoAlertDialog(
                title: Text("iOS风格的对话框"),
                content: Column(
                  children: <Widget>[
                    SizedBox(
                      height: 10,
                    ),
                    Align(
                      child: Text("你确定不关注我吗?"),
                      alignment: Alignment(0, 0),
                    ),
                  ],
                ),
                actions: <Widget>[
                  CupertinoDialogAction(
                    child: Text("取消"),
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  ),
                  CupertinoDialogAction(
                    child: Text("确定"),
                    onPressed: () {
                    },
                  ),
                ],
              );
            });
      }
    

    效果如下:

    CupertinoAlertDialog.gif

    考虑到在 Android 平台下各种复制环境情况下的兼容性,开发中还是建议少使用 IOS 风格的组件。

    五、LinearProgressIndicator 条形进度条

    LinearProgressIndicator 本身不能设置高度,可以通过一层父容器设置高度来间接设置,它的使用也是非常常见;如:通常在做下载时,给用户提示一个 条形进度条提示用户正在下载操作。

    构造函数:

      const LinearProgressIndicator({
        Key key,
        double value,
        Color backgroundColor,
        Animation<Color> valueColor,
        String semanticsLabel,
        String semanticsValue,
      })
    

    常用属性:

        属性                           描述
    
        value                          0~1的浮点数,用来表示进度值;如果 value 为 null 或空,则显示一个动画,否则显示一个定值
    
        backgroundColor                背景颜色
    
        valueColor                     animation类型的参数,用来设定进度值的颜色,默认为主题色
    

    简单运用:

      SizedBox(
        child: LinearProgressIndicator(
            //背景颜色
            backgroundColor: Colors.yellow,
            //进度颜色
            valueColor: new AlwaysStoppedAnimation<Color>(Colors.red)),
        height: 8.0,
        width: 200,
    

    效果如下:

    LinearProgressIndicator.gif

    六、CircularProgressIndicator 圆形进度条

    CircularProgressIndicator 同 LinearProgressIndicator 一样 本身不能设置高度,智能通过一层父容器设置高度来间接设置,在用法上也是如出一辙。

    常用属性:

        属性                           描述
    
        value                          0~1的浮点数,用来表示进度值;如果 value 为 null 或空,则显示一个动画,否则显示一个定值
    
        backgroundColor                背景颜色
    
        valueColor                     animation类型的参数,用来设定进度值的颜色,默认为主题色
        
        strokeWidth                    可设置进度Bar 宽度
    

    简单运用:

       new SizedBox(
            //限制进度条的高度
            height: 40.0,
            //限制进度条的宽度
            width: 40,
            child: new CircularProgressIndicator(
                strokeWidth: 3,
                //背景颜色
                backgroundColor: Colors.yellow,
                //进度颜色
                valueColor: new AlwaysStoppedAnimation<Color>(Colors.red)),
          ),
    

    效果如下:

    CircularProgressIndicator.gif

    七、自定义加载 Dialog 效果

    为了让我们的 Dialog 更加通用性,我们尽可能的让 Dialog 的样式从外部传入,用户尽可能多的能够控制它的样式。比如: 我们要实现 能够设置 Dialog 的最大显示时长,加载效果支持 圆形进度条或者条形进度条或者是他们的派生类,圆角,背景等。

    首先让我们的自定义 Widget 继承 Dialog ,如下:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    
    /*
     * creat_user: zhengzaihong
     * Email:1096877329@qq.com
     * creat_date: 2019/9/2
     * creat_time: 9:50
     * describe  自定义dialog
     **/
    
    // ignore: must_be_immutable
    class LoadingViewDialog extends Dialog {
    
      //内容布局
      final Widget content;
    
      //加载中动画
      final Widget progress;
    
      //dialog 的宽
      double dialogWidth;
    
      //dialog 的高
      double dialogHight;
    
      //dialog 的圆角度数
      double radius;
    
      // dialog 的容器布局内距
      double contentPadding;
    
      //dialog 的背景颜色
      Color backGroundColor;
    
      //dialog 的最大显示时长 单位秒。
      int maxShowTime ;
    
      LoadingViewDialog({
        Key key,
        this.dialogWidth = 120.0,
        this.dialogHight = 120.0,
        this.content,
        this.progress,
        this.radius = 8.0,
        this.contentPadding = 20,
        this.maxShowTime = 100,
        this.backGroundColor =  Colors.white
      }) :
            super(key: key);
    
      @override
      Widget build(BuildContext context) {
    
        showTimer(context);
        return new Material( //创建透明层
          type: MaterialType.transparency, //透明类型
          child: new Center( //保证控件居中效果
    
            child: new SizedBox(
              width: dialogWidth,
              height: dialogHight,
              child: new Container(
                padding: EdgeInsets.all(contentPadding),
                decoration: ShapeDecoration(
                  color: backGroundColor,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(
                      Radius.circular(radius),
                    ),
                  ),
                ),
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    progress,
                    Padding(
                      padding: const EdgeInsets.only(
                        top: 20,
                      ),
                      child: content
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    
      //添加定时
      showTimer(context) {
        Timer.periodic(Duration(milliseconds: maxShowTime*1000), (t) {
          Navigator.pop(context);
          //取消定时器
          t.cancel();
        });
      }
    
    }
    

    首先我们来看下条形进度条,实例代码如下:

    _LoadingDialog() {
    
      showDialog(
          context: context, //BuildContext对象
          barrierDismissible: false,
          builder: (BuildContext context) {
            //调用我们的自定义 对话框
            return LoadingViewDialog(
              progress: LinearProgressIndicator(
                  //背景颜色
                  backgroundColor: Colors.yellow,
                  //进度颜色
                  valueColor: AlwaysStoppedAnimation<Color>(Colors.red)
              ),
    
              content: Text(
                '正在加载...',
                style: TextStyle(color: Colors.blue),
              ),
              maxShowTime: 5,
            );
          });
    
    }
    

    无论是 Flutter 内置的对话框,还是我们继承 Dialog 自定义的 对话框都需要调用 showDialog 函数。下面我们来看下效果图:

    自定义Dialog.gif

    LoadingViewDialog 中的属性配置在代码中已经明确写出了,这里就不在一 一描述,可以看到 通过设置 maxShowTime 显示最大时长和,progress 的样式类型都是生效了的,但这种样式的可能并不常用,下面来看下开发中常用的加载样式:

    实例代码:

    _LoadingDialog() {
    
      showDialog(
          context: context, //BuildContext对象
          barrierDismissible: false,
          builder: (BuildContext context) {
            return LoadingViewDialog(
              //调用对话框
    
                progress: CircularProgressIndicator(
                  strokeWidth: 3,
                  //背景颜色
                  backgroundColor: Colors.red,
                  //进度颜色
                ),
    
              content: Text(
                '正在加载...',
                style: TextStyle(color: Colors.blue),
              ),
              maxShowTime: 5,
            );
          });
    }
    

    效果如下:

    自定义Dialog2.gif

    好了本章节到此结束,又到了说再见的时候了,如果你喜欢请留下你的小红星,你们的支持才是创作的动力,如有错误,请热心的你留言指正, 谢谢大家观看,下章再会 O(∩_∩)O

    实例源码地址: https://github.com/zhengzaihong/flutter_learn

    相关文章

      网友评论

        本文标题:Flutter第十一章(AlertDialog ,Simple

        本文链接:https://www.haomeiwen.com/subject/iuwiectx.html