得益於移動端的優勢,flutter 對話框種類還是比較多的,下面列舉幾個比較常用樣式的對話框
需要準備的 Scaffold 組件佈局如下:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("對話框"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _alertDailog,
child: const Text("alert彈出框-AlertDialog"),
),
ElevatedButton(
onPressed: _simpleDialog,
child: const Text("select彈出框-SumpleDialog"),
),
ElevatedButton(
onPressed: _modalBottomSheet,
child: const Text("model彈出框-modelBottomSheet"),
),
ElevatedButton(
onPressed: _toast,
child: const Text("toast彈出框-toast"),
),
]),
),
);
}
AlertDialog(提示對話框)#
提示對話框長這樣:
//alertDailog(注意異步)
void _alertDailog() async {
var result = await showDialog(
context: context,
barrierDismissible: false, //不允許點擊灰色背景取消
builder: (context) {
return AlertDialog(
title: const Text("我是alertDialog"),
content: Text("我是Dialog主體"),
actions: [
TextButton(
onPressed: () {
print("ok");
//關閉對話框,直接路由返回就行了
Navigator.pop(context, true);
},
child: const Text("確定")),
TextButton(
onPressed: () {
print("cancel");
Navigator.pop(context, false);
},
child: const Text("取消")),
],
);
});
print(result);
}
SimpleDialog#
普通對話框裡面是可以任意放組件的,這裡可以做 select 的功能
void _simpleDialog() async {
var res = await showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: const Text("請選擇語言"),
children: [
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, "漢語");
},
child: const Text("漢語"),
),
const Divider(),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, "英語");
},
child: const Text("英語"),
),
const Divider(),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, "日語");
},
child: const Text("日語"),
)
],
);
});
print(res);
}
showModalBottomSheet(底部彈出式模態框)#
先看效果:
這裡使用一個購物車案例演示吧:
void _modalBottomSheet() async {
var res = await showModalBottomSheet(
context: context,
builder: (context) {
return SizedBox(
height: 250,
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Row(
children: [
const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: Text(
"顏色:",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "紅色");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color.fromARGB(255, 254, 80, 42),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("紅色"),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "黃色");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color(0x00000ccc),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("黃色"),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "藍色");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color(0x00000ccc),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("藍色"),
),
),
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Row(
children: [
const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: Text(
"尺寸:",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "XL");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color.fromARGB(255, 254, 80, 42),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("XL"),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "XML");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color(0x00000ccc),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("XML"),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "XXL");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Color(0x00000ccc),
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)),
),
),
child: const Text("XXL"),
),
),
],
),
),
SizedBox(
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "ok");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Colors.red,
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
),
child: const SizedBox(
width: 150,
height: 40,
child: Center(
child: Text("加入購物車"),
),
),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context, "ok購買");
},
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
Colors.orange,
),
shape: MaterialStateProperty.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
),
child: const SizedBox(
width: 150,
height: 40,
child: Center(
child: Text("立即購買"),
),
),
),
),
],
),
),
],
),
);
});
print(res);
}
Fluttertoast (氣泡消息)#
注:flutter 沒有自帶 toast,需要去倉庫裝一個
flutter pub add fluttertoast
使用 toast:
void _toast() {
Fluttertoast.showToast(
msg: "toast哦",
toastLength: Toast.LENGTH_SHORT, //安卓平台有效(toast顯示時長
gravity: ToastGravity.CENTER, //方位
timeInSecForIosWeb: 1, //提示時間 針對ios和web
backgroundColor: Colors.red, //背景顏色
textColor: Colors.red, //文本顏色
fontSize: 16.0, //文本字體大小
);
}
效果:
自定義 Dailog#
在 Flutter 中,可以通過showDialog
中的 builder 函數來添加返回自定義 Widget
//自定義Dialog
void _myDialog() async {
var res = await showDialog(
context: context,
//點擊灰色背景不會消失
barrierDismissible: false,
builder: (context) {
//使用自定義Dailog
return MyDailog(
title: "kano",
content: "kanokano.cn",
onTap: () {
//異步事件
Navigator.pop(context, '關閉啦');
},
);
});
print(res);
}
MyDialog.dart
import 'package:flutter/material.dart';
class MyDailog extends Dialog {
late String title;
late String content;
late Function()? onTap;
MyDailog(
{Key? key,
required this.title,
required this.content,
required this.onTap})
: super(key: key);
@override
Widget build(BuildContext context) {
//Material組件可以設置背景透明,所以我們用它
return Material(
//設置成透明(順便激活了點擊外側關閉對話框的功能)
type: MaterialType.transparency,
//點擊灰色背景不會消失
child: Center(//包裹一個Center,這樣就不會造成對話框全屏覆蓋了
child: Container(
height: 300,
width: 300,
padding: const EdgeInsets.all(10),
color: Colors.white,
child: Column(
children: [
Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(title),
),
Align(
alignment: Alignment.topRight,
//InkWell裡面有各種點擊事件和交互事件
child: InkWell(
onTap: onTap,
child: const Icon(Icons.close),
),
),
],
),
const Divider(),
Container(
padding: const EdgeInsets.all(10),
width: double.infinity,
child: Text(content),
)
],
)),
),
);
}
}