地球人已經抵擋不住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,查看完整代碼。