Dialog在不同的平台,都是一种重要的交互方式,在Flutter中,Dialog也是有很多种,但大多数场景的交互,都需要根据项目的主题或一些特定的交互去实现自定义的Dialog。
为满足不同的诉求和兼容性,封装实现了两种不同的Dialog工具,可根据自己的要求,进行填充内容。
一,实现通用的自定义Dialog
根据Dialog的特性,进行抽离封装,具体内容,可自行填充或扩展
Dart
static Future<T?> showCenterDialog<T>(BuildContext context,
{bool barrierDismissible = true,
required List<Widget> child,EdgeInsetsGeometry ? padding,double? radius}) async{
return await showDialog<T>(
context: context,
barrierDismissible: barrierDismissible,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () {
return Future.value(barrierDismissible);
},
child: Scaffold(
backgroundColor:Colors.transparent,
body: Center(
child: SingleChildScrollView(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 18),
padding: padding,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(radius??0))
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children:child,
),),
),
),
resizeToAvoidBottomInset: true,
),
);
},
);
}
使用时:
Dart
showCenterDialog(context, child: [
const Text('Hello Word')
]);
二,自定义bottomSheet实现高度可定制,内容可扩展的底部弹框
Dart
showBottomSelectDialog(BuildContext context, {required Widget child}) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(6), topRight: Radius.circular(6))),
isScrollControlled: true,
enableDrag: false,
constraints: const BoxConstraints(
minWidth: 0,
minHeight: 0,
maxWidth: double.infinity,
maxHeight: double.infinity),
builder: (context) => child);
}
使用时:
Dart
showBottomSelectDialog(context, child:Container(
height: 300,
width: double.infinity,
child: const Column(
children: [
Text('Hello Flutter')
],
),
));
三,自定义Dialog中遇到的问题
在Flutter3.13版本之后,普通Dialog中使用TextField,键盘关闭时,TextField内容会被清空
这是可以把Dialog中的内容放到一个StatefullWidget中,即可解决。
例如:
Dart
class WarningPage extends StatefulWidget{
final String title;
final String message;
const WarningPage({super.key,this.title ="Tips",this.message ="Error"});
@override
State<StatefulWidget> createState() {
return _WarningState();
}
}
class _WarningState extends State<WarningPage>{
@override
Widget build(BuildContext context) {
return Material(
type: MaterialType.transparency, //透明类型
child: Center(
child: Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 18),
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(widget.title),
Text(widget.message)
],
),
),
),
);
}
}
使用时:
Dart
await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () {
return Future.value(true);
},
child: const WarningPage(title: 'App',message: "Hello Flutter"),
);
},
);
如上示例,仅提供了一种通用封装的实现,可结合实际项目自行扩展与实现。