Dialog在不同的平台,都是一种重要的交互方式,在Flutter中,Dialog也是有很多种,但大多数场景的交互,都需要根据项目的主题或一些特定的交互去实现自定义的Dialog。
为满足不同的诉求和兼容性,封装实现了两种不同的Dialog工具,可根据自己的要求,进行填充内容。
一,实现通用的自定义Dialog
根据Dialog的特性,进行抽离封装,具体内容,可自行填充或扩展
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,),);},);}
使用时:
showCenterDialog(context, child: [const Text('Hello Word')]);
二,自定义bottomSheet实现高度可定制,内容可扩展的底部弹框
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);}
使用时:
showBottomSelectDialog(context, child:Container(height: 300,width: double.infinity,child: const Column(children: [Text('Hello Flutter')],),));
三,自定义Dialog中遇到的问题
在Flutter3.13版本之后,普通Dialog中使用TextField,键盘关闭时,TextField内容会被清空
这是可以把Dialog中的内容放到一个StatefullWidget中,即可解决。
例如:
class WarningPage extends StatefulWidget{final String title;final String message;const WarningPage({super.key,this.title ="Tips",this.message ="Error"});@overrideState<StatefulWidget> createState() {return _WarningState();}
}class _WarningState extends State<WarningPage>{@overrideWidget 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)],),),),);}
}
使用时:
await showDialog(context: context,barrierDismissible: false,builder: (BuildContext context) {return WillPopScope(onWillPop: () {return Future.value(true);},child: const WarningPage(title: 'App',message: "Hello Flutter"),);},);
如上示例,仅提供了一种通用封装的实现,可结合实际项目自行扩展与实现。