對話方塊作為一個挺重要的東西,這裡來說一下,細細一數也蠻多的,本文包括
[1].SimpleDialog
[2].AlertDialog
[3].CupertinoAlertDialog
[4].Dialog中的元件狀態更新
[5].SnackBar
[6].BottomSheet
複製程式碼
0.搭個場子再說
class DialogShow extends StatefulWidget {
@override
_DialogShowState createState() => _DialogShowState();
}
class _DialogShowState extends State<DialogShow> {
@override
Widget build(BuildContext context) {
var title = Container(
alignment: AlignmentDirectional.center,
child: Text(
"Dialog Unit",
style: TextStyle(fontSize: 30),
),
);
Map<String, Function> buttons = {
"對話方塊SimpleDialog": _showSimpleDialog,
"對話方塊AlertDialog": _showAlertDialog,
"對話方塊CupertinoAlertDialog": _showCupertinoAlertDialog,
"對話方塊顯示自己": _showWidgetDialog,
"對話方塊顯示StatefulWidget": _showStatefulWidgetDialog,
"Scaffold": _showScaffold,
"BottomSheet": _showBottomSheet,
};
var btns= buttons.keys.toList().map((str){//構建按鈕元件列表
return RaisedButton(
onPressed: () {
buttons[str](context);
},
child: Text(str),
);
}).toList();
var result =Column(children: <Widget>[title,Column(
children: btns,
)],) ;
return result;
}
}
複製程式碼
1.對話方塊:SimpleDialog
通過showDialog來建立對話方塊,傳入BuildContext物件,通過builder構造器來建立元件
簡單的對話方塊,只要一條條的東西可以選擇SimpleDialog,比如:
_showSimpleDialog(BuildContext context) {
var strs=['雲深不知處內亥時息,卯時起',
"雲深不知處內不可挑食留剩,不可境內殺生",
"雲深不知處內不可私自鬥毆,不可淫亂",
"雲深不知處禁止魏無羨入內,不可吹笛"];
var title = Row(//標題
children: <Widget>[
Image.asset("images/icon_lwj.png", width: 30,height: 30,),
SizedBox(width: 10,),
new Text("藍氏家規")],
);
showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: title,
children: strs.map((str){
return SimpleDialogOption(
child: Row(children: <Widget>[
Icon(Icons.turned_in_not,color: Colors.blue,),Text(str)],) ,
onPressed: () {
Navigator.of(context).pop(str);
print(str);
},
);
}).toList(),
);
});
}
複製程式碼
3.對話方塊:AlertDialog
AlertDialog元件包括標題(title)、內容(content)、actions(行為),還有一些陰影,顏色形狀等輔助屬性。
_showAlertDialog(BuildContext context) {
var title = Row(//標題
children: <Widget>[
Image.asset("images/icon_wwx.png", width: 30,height: 30,),
SizedBox(width: 10,),
new Text("表白")],
);
var content = Row(//內容
children: <Widget>[
Text("我?你,你是我的"),
Image.asset("images/icon_ylm.png",width: 30, height: 30, )],
);
showDialog(
context: context,
builder: (context) => //構造器
AlertDialog(title: title, content: content, actions: <Widget>[
FlatButton(
child: Text("不要鬧"),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text("走開"),
onPressed: () {
Navigator.of(context).pop();
},
)
]));
}
複製程式碼
3.對話方塊:CupertinoAlertDialog
Cupertino風格的對話方塊
void _showCupertinoAlertDialog(BuildContext context) {
var title = Row(//標題
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset("images/icon_wwx.png", width: 30,height: 30,),
SizedBox(width: 10,),
new Text("表白")],
);
var content = Row(
children: <Widget>[
Text("我?你,你是我的",style: TextStyle(fontSize: 20),),
Image.asset("images/icon_ylm.png", width: 40, height: 40, ) ],
);
var dialog = CupertinoAlertDialog(
content: content,
title: title,
actions: <Widget>[
CupertinoButton( child: Text("不要鬧"),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton( child: Text("走開"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
showDialog(context: context, builder: (context) => dialog);
}
複製程式碼
4.瞎玩一下
既然對話方塊裡面顯示的是一個Widget,那我把它自己顯示出了會怎麼樣?
現在Dialog應該不難玩了吧,既然什麼Widget都能放進去,還有什麼好怕的。
_showWidgetDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return this.widget;
});
}
複製程式碼
5.對話方塊中的StatefulWidget
想要更新對話方塊裡的元件狀態,可以用StatefulBuilder,裡面回撥的StateSetter物件
_showStatefulWidgetDialog(BuildContext context) {
var progress = 0.0;
StateSetter stateSetter;
Timer.periodic(Duration(milliseconds: 100), (timer) {//計時器模擬進度增加
progress += 0.1;
if (stateSetter != null) {
stateSetter(() {});
}
if (progress >= 1) {
timer.cancel();
stateSetter = null;
Navigator.of(context).pop();
}
});
var statefulBuilder = StatefulBuilder(
builder: (ctx, state) {
stateSetter = state;
return Center(
child: SizedBox(width: 150, height: 150,
child: Card(elevation: 24.0,
color: Colors.blue.withAlpha(240),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
value: progress,
),
SizedBox(height: 20,),
Text("Loading...",
style: TextStyle(color: Colors.white),),
SizedBox(height: 5,),
Text("done ${((progress-0.1) * 100).toStringAsFixed(1)}%",
style: TextStyle(color: Colors.white),),
],
),
),
),
);
},
);
showDialog(context: context, builder: (ctx) => statefulBuilder);
}
複製程式碼
6.底部彈框:SnackBar
這個比較簡單,使用Scaffold.of方法獲取ScaffoldState呼叫showSnackBar
_showScaffold(BuildContext context) {
var snackBar = SnackBar(
backgroundColor: Color(0xffFB6431),//顏色
content: Text('Hello!'),//內容
duration: Duration(seconds: 3),//持續時間
action: SnackBarAction(
label: '確定',
onPressed: () {
print("Flutter之旅");
}));
Scaffold.of(context).showSnackBar(snackBar);//這樣就行了
}
複製程式碼
7.底部抽屜:BottomSheet
用法和SnackBar相似,更強的是底部欄的child你想放什麼都可以。
bool _showing=false;
_showBottomSheet(BuildContext context) {
var bottomSheet = BottomSheet(
onClosing: () {},
builder: (context) => (Container(
color: Color(0xdde3fbf6),
height: 150,
child: Center(
child: Image.asset("images/wy_300x200_filter.jpg"),
),
)));
if(_showing){
Navigator.of(context).pop();
}else{
Scaffold.of(context).showBottomSheet(bottomSheet.builder); //這樣就行了
}
_showing=!_showing;
}
複製程式碼
好了,本文就到這裡。
結語
本文到此接近尾聲了,如果想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品;如果想細細探究它,那就跟隨我的腳步,完成一次Flutter之旅。
另外本人有一個Flutter微信交流群,歡迎小夥伴加入,共同探討Flutter的問題,本人微訊號:zdl1994328
,期待與你的交流與切磋。