前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter 专题】24 图解自定义 Dialog 对话框

【Flutter 专题】24 图解自定义 Dialog 对话框

作者头像
阿策小和尚
发布2019-08-12 16:18:47
1.4K0
发布2019-08-12 16:18:47
举报
文章被收录于专栏:阿策小和尚阿策小和尚

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

1. 继承 Dialog

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

2. 绘制 Dialog 样式

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

代码语言:javascript
复制
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. 内容传参

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

代码语言:javascript
复制
class GenderChooseDialog extends Dialog {

  var title;

  GenderChooseDialog({
    Key key,
    @required this.title,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) { }
}
4. 添加点击事件

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

代码语言:javascript
复制
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 设置内容和点击事件等;
代码语言:javascript
复制
GenderChooseDialog({
  Key key,
  @required this.title,
  @required this.onBoyChooseEvent,
  @required this.onGirlChooseEvent,
}) : super(key: key);
  1. showDialog 方法中,barrierDismissible: false 属性代表点击顶部状态栏(显示电量/时间的横条位置)时是否关闭对话框,如果想点击半透明位置时关闭对话框,可以再添加一个点击事件即可。

和尚目前的学习还仅限于基本的使用,如果又不对的地方还希望多多指出。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿策小和尚 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 继承 Dialog
  • 2. 绘制 Dialog 样式
  • 3. 内容传参
  • 4. 添加点击事件
  • 5. 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档