Flutter学习: 弹出Dialog的简单使用

分享的是一个常用功能——弹出Dialog,对于Flutter,万物皆Widget,所以弹出一个Dialog也是加上一个Widget,具体的api就是showDialog。不过不同于原生,Flutter的showDialog本质上是push一个新的路由。具体可以看showDialog的源码:

可以看到,本质就是调用Navigator.of().push进入一个新的路由。而这个新的路由就是我们的Dialog。

例子

了解了showDialog 的原理之后,我们开始进入写例子的环节,页面如下:

是一个嵌套了radio的Dialog效果。 首先,我采用的是系统提供的AlertDialog类,AlertDialog有三个我们需要用到的属性,分别是title, actions, content, 顾名思义title就是上面的标题, actions是底下的确定和取消按钮,content是中间的内容部分即radio。

首先,我抽象了一个自定义的AlertDialog,自定义了一些基本样式和保留了一些属性。

import 'package:flutter/material.dart';

import '../common_widget.dart';

class CustomAlertDialog extends StatelessWidget {
  CustomAlertDialog({Key key, @required this.title, @required this.contentWidget, this.showCancel = true, this.showConfirm = true, this.actionWidgets}) : super(key: key);

  final bool showCancel;
  final bool showConfirm;
  final String title;
  final Widget contentWidget;
  final List<Widget> actionWidgets;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
        title: Common.primaryBigTitle(content: title),
        elevation: 12.0,
        titlePadding: EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 12),
        contentPadding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(8.0)),
        ),
        actions: _buildActionWidget(context),
        content: contentWidget);
  }

  _buildActionWidget(BuildContext context) {
    List<Widget> actionWidgets = this.actionWidgets;
    if (actionWidgets == null) {
      actionWidgets = [];
      if(showConfirm) {
        actionWidgets.add(FlatButton(onPressed: () => Navigator.of(context).pop(), child: Text("确定")));
      }
      if(showCancel) {
        actionWidgets.add(FlatButton(onPressed: () => Navigator.of(context).pop(), child: Text("取消")));
      }
    }
    return actionWidgets;
  }
}

复制代码

接着,我自定义了radioDialog,如下:


import 'package:flutter/material.dart';

import '../common_widget.dart';
import 'custom_alert_dialog.dart';

class RadioAlertDialog extends StatelessWidget {
  RadioAlertDialog({Key key, @required this.title, @required this.selectValue, this.showCancel = true, this.showConfirm = true, @required this.valueList}) : super(key: key);

  final bool showCancel;
  final bool showConfirm;
  final String title;
  final String selectValue;
  final List<String> valueList;

  @override
  Widget build(BuildContext context) {
    return CustomAlertDialog(
      title: title,
      contentWidget:Container(child: Column(mainAxisSize: MainAxisSize.min, children: _buildRadioList(context))),
      showCancel: showCancel,
      showConfirm: showConfirm,
    );
  }

  _buildRadioList(BuildContext context) {
    List<Widget> radioList = [];
    valueList.forEach((String value) => radioList.add(RadioListTile<String>(
        value: value,
        title: Common.primaryTitle(content: value),
        activeColor: Colors.blue,
        groupValue: '$selectValue',
        onChanged: (value) {
          Navigator.of(context).pop(value);
        })));
    return radioList;
  }
}

复制代码

完成了这两个widget的自定义之后,接下来就简单了,用showDialog调用就好:


   showDialog<String>(
              context: context,
              builder: (context) {
                String selectValue = '${settingsStore.showPage}';
                List<String> valueList = ["首页", "生活"];
                return RadioAlertDialog(title: "选择展示页面",
                    selectValue: selectValue,
                    valueList: valueList);
              }).then((value) {
                print(value);
                settingsStore.saveShowPage(value);
          });

复制代码

把需要展示的radio文本数组和选中的文本传递进去即可,细心的朋友发现在showDialog还调用了then去做逻辑处理。前面有讲到,其实showDialog本质上也是push了路由,Flutter支持路由pop之后传递参数回到上一个页面,所以在radio选中之后调用 Navigator.of(context).pop(value),即可把选中的文本回传给上一个widget。

总结

本篇主要介绍了Flutter的Dialog的简单使用,在Flutter的世界里,万物皆Widget,所以Dialog也是push一个新的widget,这样一来,既没有打断路由的体系,并且更方便理解整个widget的交互。

仓库

点击flutter_demo,查看完整代码。

作者:少年阿涛
链接:https://juejin.im/post/5cf236d8f265da1bc23f5fbf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

THE END