Flutter 24: 图解自定义 Dialog 对话框

作者: 阿策神奇 | 来源:发表于2018-11-30 22:14 被阅读10次

          Dialog 在我们的日常开发中是必不可少的,Flutter 也提供了 AlertDialog / SimpleDialog 供我们选择,但是对于开发还是不足够的,小菜尝试了一下自定义对话框,简单记录一下。

    1. 继承 Dialog

          Dialog 只是一个基础的 Widget 不会直接使用,小菜想自定义 Dialog 必须先继承 Dialog。此时需要重写 Widget build(BuildContext context) 方法。

    2. 绘制 Dialog 样式

          小菜尝试做一个性别选择框,包括标题,图片和按钮等。

    import 'package:flutter/material.dart';
    
    class GenderChooseDialog extends Dialog {
      GenderChooseDialog({
        Key key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return new Padding(
            padding: const EdgeInsets.all(12.0),
            child: new Material(
                type: MaterialType.transparency,
                child: new Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      new Container(
                          decoration: ShapeDecoration(
                              color: Color(0xFFFFFFFF),
                              shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.all(
                                Radius.circular(8.0),
                              ))),
                          margin: const EdgeInsets.all(12.0),
                          child: new Column(children: <Widget>[
                            new Padding(
                                padding: const EdgeInsets.fromLTRB(
                                    10.0, 40.0, 10.0, 28.0),
                                child: Center(
                                    child: new Text('请选择性别',
                                        style: new TextStyle(
                                          fontSize: 20.0,
                                        )))),
                            new Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                mainAxisSize: MainAxisSize.max,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: <Widget>[
                                  _genderChooseItemWid(1),
                                  _genderChooseItemWid(2)
                                ])
                          ]))
                    ])));
      }
    
      Widget _genderChooseItemWid(var gender) {
        return GestureDetector(
            child: Column(children: <Widget>[
          Image.asset(
              gender == 1
                  ? 'images/icon_type_boy.png'
                  : 'images/icon_type_girl.png',
              width: 135.0,
              height: 135.0),
          Padding(
              padding: EdgeInsets.fromLTRB(0.0, 22.0, 0.0, 40.0),
              child: Text(gender == 1 ? '我是男生' : '我是女生',
                  style: TextStyle(
                      color: Color(gender == 1 ? 0xff4285f4 : 0xffff4444),
                      fontSize: 15.0)))
        ]));
      }
    }
    

    3. 内容传参

          小菜尽量把对话框做到通用性强一些,小菜测试仅把标题当参数传递,一个参数与多个参数是类似的。

    class GenderChooseDialog extends Dialog {
      
      var title;
      
      GenderChooseDialog({
        Key key,
        @required this.title,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) { }
    }
    

    4. 添加点击事件

          每个对话框要有自己的点击事件,小菜准备把点击不同图片或文字时添加不同的点击事件。需要自定义 Function 方法。

    class GenderChooseDialog extends Dialog {
      var title;
      Function onBoyChooseEvent;
      Function onGirlChooseEvent;
    
      GenderChooseDialog({
        Key key,
        @required this.title,
        @required this.onBoyChooseEvent,
        @required this.onGirlChooseEvent,
      }) : super(key: key);
      
      Widget _genderChooseItemWid(var gender) {
        return GestureDetector(
            onTap: gender == 1 ? this.onBoyChooseEvent : this.onGirlChooseEvent,
            child: Column(children: <Widget>[
              Image.asset(
                  gender == 1 ? 'images/icon_type_boy.png'
                      : 'images/icon_type_girl.png',
                  width: 135.0, height: 135.0),
              Padding(
                  padding: EdgeInsets.fromLTRB(0.0, 22.0, 0.0, 40.0),
                  child: Text(gender == 1 ? '我是男生' : '我是女生',
                      style: TextStyle(
                          color: Color(gender == 1 ? 0xff4285f4 : 0xffff4444),
                          fontSize: 15.0)))
            ]));
      }
    }
    
    // 方法调用
    void _onItemPressed() {
      showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return GenderChooseDialog(
                title: '小哥哥小姐姐请选择',
                onBoyChooseEvent: () {
                  Navigator.pop(context);
                },
                onGirlChooseEvent: () {
                  Navigator.pop(context);
                });
          });
    }
    

    5. 注意事项

    1. Dialog 也是 Widget 默认是占满全屏,所以小菜自己绘制部分对话框,为了协调,借助 type: MaterialType.transparency 设置了对话框外半透明效果;
    2. 无论是传参还是设置点击事件,都需要在初始化中添加,很像 Android 中对 RecycleView 设置内容和点击事件等;
    GenderChooseDialog({
      Key key,
      @required this.title,
      @required this.onBoyChooseEvent,
      @required this.onGirlChooseEvent,
    }) : super(key: key);
    
    1. showDialog 方法中,barrierDismissible: false 属性代表点击顶部状态栏(显示电量/时间的横条位置)时是否关闭对话框,如果想点击半透明位置时关闭对话框,可以再添加一个点击事件即可。

          小菜目前的学习还仅限于基本的使用,如果又不对的地方还希望多多指出。以下是小菜公众号,欢迎闲来吐槽~


    公众号.jpg

    相关文章

      网友评论

        本文标题:Flutter 24: 图解自定义 Dialog 对话框

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