持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
通过之前的介绍,我们根据Flutter的AlertDialog组件,已经实现了如下的弹窗显示方法:
但该方法的复用性并不高,我们可以发现,像弹窗的内容主体、弹窗的按钮组这些内容我们都给写死了,而不是通过调用方法传入显示的,这样会代码的复用性并不高,当需要显示另一种不同的弹窗类型时,又需要进行大量的代码修改,因此我们可以将其封装一下。原本代码如下:
Future<bool?> showLoginConfirmDialog(BuildContext context) {
return showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
content: Container(
height: 300.h,
width: 336.w,
alignment: Alignment.center,
child: Image.asset('assets/images/login/login_hint.png',
width: 169.w, height: 179.h),
),
actions: <Widget>[
Container(
alignment: Alignment.center,
child: MaterialButton(
onPressed: () {
Get.offAllNamed("/login");
},
color: lightPrimaryColor,
height: 44.h,
minWidth: double.infinity,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: const Text(
'立即登录',
style: TextStyle(color: Colors.white),
)))
],
);
},
);
}
弹窗的内容跟按钮组是通过content和actions这两个属性的Widget值来显示的,因此我们可以将其抽为showLoginConfirmDialog该方法的参数,调用该方法时传入需要自定义的弹窗内容主体Widget和按钮内容的List类型的Widget即可。
因此我们进行以下的封装,给该方法增加两个参数,类型都为Widget即可:
Future<bool?> showDeleteConfirmDialog(
BuildContext context, Widget contentWidge, Widget actionsWidgetLsit) {
return showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
contentPadding: EdgeInsets.only(top: 30.h),
content: contentWidge,
actions: <Widget> actionsWidgetLsit,
);
},
);
}
当我们需要调用时,传入自定义的内容Widget组件跟按钮组Widget组件即可:
showDeleteConfirmDialog(
context,
Text('账号密码错误,请重新填写'),
[
Container(
alignment: Alignment.center,
child: GestureDetector(
onTap: () => Navigator.of(context).pop(true),
child: const Text('确定')))
]
)
更加上面代码调用后,弹窗如下:
showDeleteConfirmDialog(
context,
Container(
height: 60.h,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(width: 1.w, color: const Color(0xFFE5E5E5))),
),
child: Container(
padding: EdgeInsets.only(bottom: 20.h),
child: const Text("请先前往身份认证",
style: TextStyle(color: Color(0xFF333333)))),
[
Flex(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: Axis.horizontal,
children: [
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.zero,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border(
right: BorderSide(
width: 1.w,
color: const Color(0xFFE5E5E5))),
),
child: GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: const Text("取消",
style: TextStyle(color: secondColor))))),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.zero,
child: Container(
alignment: Alignment.center,
child: GestureDetector(
onTap: () => Navigator.of(context).pop(true),
child: Container(
child: const Text("前往认证",
style: TextStyle(color: secondColor))))),
)),
],
)
]
)
上述代码实现的弹窗效果图下:
可以看见,经过封装后,如果弹窗的Ui发生改变,我们只需要在调用showDeleteConfirmDialog的时候,传入需要改变的Widget组件即可,我只对内容Widget跟按钮Widget进行了提取封装,读者可以根据自己的需求,在该基础上继续封装,把不变的都写在同一个方法内,变的作为参数传入,这也是封装的思想,从而达到提高代码复用。