Flutter第十一章(AlertDialog ,SimpleDialog ,showModalBottomSheet,CupertionDialogAction ,LinearProgres...

版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!

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

欢迎来到本章节,上一章节介绍了常用可滚动组件的使用,知识点回顾 戳这里 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 showDialog({
      @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 {

    _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: [
                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 这意味着我们可以在这里面自定义各种各样的组件和样式。

简单运用:

  _simpleDialog() async{

    var result= await  showDialog(

        barrierDismissible:false,
        context:context,
        builder: (context){
          return SimpleDialog(
            title:Text("选择内容",style: TextStyle(color: Colors.blue)),
            children: [

              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: [
                Container(
                  height: 50,
                  child: Center(
                    child: Text(
                      "分享",
                      style: TextStyle(color: Colors.black54),
                    ),
                  ),
                ),
                Divider(),
                Row(
                  mainAxisAlignment:MainAxisAlignment.center,
                  children: [

                    Container(
                      width: 80,
                      color: Colors.white,
                      child: Column(children: [
                        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: [
                          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: [
                          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: [
                SizedBox(
                  height: 10,
                ),
                Align(
                  child: Text("你确定不关注我吗?"),
                  alignment: Alignment(0, 0),
                ),
              ],
            ),
            actions: [
              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 valueColor,
    String semanticsLabel,
    String semanticsValue,
  })

常用属性:

    属性                           描述

    value                          0~1的浮点数,用来表示进度值;如果 value 为 null 或空,则显示一个动画,否则显示一个定值

    backgroundColor                背景颜色

    valueColor                     animation类型的参数,用来设定进度值的颜色,默认为主题色

简单运用:

  SizedBox(
    child: LinearProgressIndicator(
        //背景颜色
        backgroundColor: Colors.yellow,
        //进度颜色
        valueColor: new AlwaysStoppedAnimation(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(Colors.red)),
      ),

效果如下:

CircularProgressIndicator.gif

七、自定义加载 Dialog 效果

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

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

import 'dart:async';

import 'package:flutter/material.dart';

/*
 * creat_user: zhengzaihong
 * Email:[email protected]
 * 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: [
                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(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 ,SimpleDialog ,showModalBottomSheet,CupertionDialogAction ,LinearProgres...)