前言
在flutter开发中,由于flutter原生的人是 google,所以很多控件外观偏向与android,很多控件android开发自己的都看不过去了(相比与ios),因此需要自己定制
这里简介一下 flutter 如何定制弹窗层
系统Dialog的使用
系统Dialog的使用如下所示,使用之前需要调用showDialog,通过该方法可以直接跳出弹层(无需写入到build中),弹层内的组件在 builder参数里面传入,这里默认传入系统的 AlertDialog
showDialog(
context: context,
barrierColor: Colors.transparent, //设置透明底色,自定义也可能会用到
builder: (BuildContext context) {
return AlertDialog(
title: const Text("测试标题"),
content: const Text("测试内容"),
actions: [
TextButton(
onPressed: () {},
child: const Text('确认'),
),
TextButton(
onPressed: () {},
child: const Text('取消'),
),
],
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
);
},
);
效果如下所以,感觉有点丑
定制 Dialog
showDialog 弹出的弹层,相当于push跳转到了系统预制的一个Popup组件中,因此内部返回时需要自己pop,另外可以把它当做跳转弹层的入口即可,我们的组件只需要继承 Dialog空白组件即可
如下所示,我们自定义弹窗(纯提供方案,不求效果😂),继承自 Dialog,相当于一个新页面,我们想编辑新页面一样编辑弹窗即可
注意:我们的组件相当于嵌入到 Dialog中的一个Container中,因此如果想改变默认底色,需要在 showDialog中设置barrierColor属性即可
//这个弹层一般是通过 showDialog 弹出,实际上相当于跳转了一个新界面,因此返回需通过 Navigator pop回去
class DialogView extends Dialog {
final String title;
final String message;
const DialogView({Key? key, required this.title, required this.message})
: super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 100,
height: 140,
color: const Color.fromRGBO(0, 0, 0, 0.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(title, style: const TextStyle(color: Colors.white)),
Text(message, style: const TextStyle(color: Colors.white)),
TextButton(
onPressed: () {
//showDialog相当于push,因此自己返回需要pop
Navigator.pop(context);
},
child: const Text('返回'),
),
],
),
),
);
}
}
调用方法如下所示,默认最底层的颜色,需要在这里设置 barrierColor
showDialog(
context: context,
barrierColor: Colors.transparent, //设置透明底色
builder: (BuildContext context) {
return const DialogView(
title: "测试标题",
message: "测试内容",
);
},
);
获取组件偏移量
开发弹层时,可能需要默认组件的位置信息,因此我们可以像 PopupMenuButton一样封装,接收一个组件,在弹出时,通过下面方法计算组件位置,从而更好的定制弹窗
组件渲染完成之后,可以通过组价你的context参数,间接获取组件的偏移量
RenderBox box = context.findRenderObject() as RenderBox;
final local = box.localToGlobal(Offset.zero);
print(local);
最后
这里只是记录一下一些常用的内容,有些内容也比较简单,仅供参考哈😂