地球人已经抵挡不住Flutter的火爆了,将来属于跨平台的时代,因此笔者最近也在开始学习Fullter,因此准备在掘金社区记录本身的学习过程,和各位同行一块儿探讨和学习。笔者的Flutter练手项目代码都放在flutter_demo,有须要的能够star噢。git
今天分享的是一个经常使用功能——弹出Dialog,对于Flutter,万物皆Widget,因此弹出一个Dialog也是加上一个Widget,具体的api就是showDialog。不过不一样于原生,Flutter的showDialog本质上是push一个新的路由。具体能够看showDialog的源码:github
能够看到,本质就是调用Navigator.of().push进入一个新的路由。而这个新的路由就是咱们的Dialog。api
了解了showDialog 的原理以后,咱们开始进入写例子的环节,页面以下:数组
是一个嵌套了radio的Dialog效果。 首先,我采用的是系统提供的AlertDialog类,AlertDialog有三个咱们须要用到的属性,分别是title, actions, content, 顾名思义title就是上面的标题, actions是底下的肯定和取消按钮,content是中间的内容部分即radio。less
首先,我抽象了一个自定义的AlertDialog,自定义了一些基本样式和保留了一些属性。ide
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,以下:post
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。ui
本篇主要介绍了Flutter的Dialog的简单使用,在Flutter的世界里,万物皆Widget,因此Dialog也是push一个新的widget,这样一来,既没有打断路由的体系,而且更方便理解整个widget的交互。this
点击flutter_demo,查看完整代码。