Flutter中自定义Dialog

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"),
        );
      },
    );

如上示例,仅提供了一种通用封装的实现,可结合实际项目自行扩展与实现。

相关推荐
AiFlutter13 小时前
Flutter之Package教程
flutter
Mingyueyixi17 小时前
Flutter Spacer引发的The ParentDataWidget Expanded(flex: 1) 惨案
前端·flutter
crasowas1 天前
Flutter问题记录 - 适配Xcode 16和iOS 18
flutter·ios·xcode
老田低代码2 天前
Dart自从引入null check后写Flutter App总有一种难受的感觉
前端·flutter
AiFlutter2 天前
Flutter Web首次加载时添加动画
前端·flutter
ZemanZhang4 天前
Flutter启动无法运行热重载
flutter
AiFlutter4 天前
Flutter-底部选择弹窗(showModalBottomSheet)
flutter
帅次5 天前
Android Studio:驱动高效开发的全方位智能平台
android·ide·flutter·kotlin·gradle·android studio·android jetpack
程序者王大川5 天前
【前端】Flutter vs uni-app:性能对比分析
前端·flutter·uni-app·安卓·全栈·性能分析·原生
yang2952423615 天前
使用 Vue.js 将数据对象的值放入另一个数据对象中
前端·vue.js·flutter