flutter所有弹窗方法以及测试效果

44 阅读4分钟
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:myapp/app/constants/app_core_import.dart';
import 'package:myapp/app/widgets/fan/myGestureDetector.dart';

/// TODO 通用弹窗方法
class Mydialog {
  /// 最常用的对话框,支持标题、内容、按钮。
  static void showAlertDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text("提示"),
        content: const Text("确定删除吗?"),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("取消"),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("确定"),
          ),
        ],
      ),
    );
  }

  /// 简单选择对话框,常用于选项列表。
  static void showSimpleDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) => SimpleDialog(
        title: const Text("选择颜色"),
        children: [
          SimpleDialogOption(
            onPressed: () => Navigator.pop(context, "红色"),
            child: const Text("红色"),
          ),
          SimpleDialogOption(
            onPressed: () => Navigator.pop(context, "蓝色"),
            child: const Text("蓝色"),
          ),
        ],
      ),
    );
  }

  /// 基础对话框,可以自定义内容。
  static Future showMyDialog(BuildContext context) async {
    return await showDialog(
      context: context,
      barrierColor: Colors.black26, //遮罩层颜色
      animationStyle: const AnimationStyle(
        curve: Curves.easeOutBack,
        duration: Duration(milliseconds: 260),
        reverseCurve: Curves.easeIn,
        reverseDuration: Duration(milliseconds: 180),
      ),
      builder: (context) => Container(
        alignment: Alignment.center,
        margin: EdgeInsets.symmetric(
          vertical: ScreenAdapter.height(300),
          horizontal: ScreenAdapter.width(50),
        ),
        color: Colors.white,
        child: TextButton(
          child: const Text("自定义内容"),
          onPressed: () {
            Navigator.pop(context, "红色");
          },
        ),
      ),
    );
  }

  /// 底部弹出框(Bottom Sheet),可模态或半透明。
  static void showMyModalBottomSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true, // 允许内容高度自适应屏幕
      backgroundColor: Colors.transparent, // 背景透明,以便自定义圆角
      builder: (context) {
        return Padding(
          padding: const EdgeInsets.all(16.0), // 整体四周边距
          child: Container(
            width: ScreenAdapter.width(350),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(16), // 圆角
            ),
            padding: const EdgeInsets.all(16), // 内部内容边距
            child: Column(
              mainAxisSize: MainAxisSize.min, // 根据内容高度自适应
              children: [
                const Text('这是底部弹框'),
                const SizedBox(height: 10),
                ElevatedButton(
                  onPressed: () => Navigator.pop(context),
                  child: const Text('关闭'),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  /// 语言选择底部弹窗
  static Future showBottomLangueSelect(
    BuildContext context,
    Widget child, {
    Function()? onTap,
  }) {
    return showModalBottomSheet(
      context: context,
      isScrollControlled: true, // 允许内容高度自适应屏幕
      backgroundColor: Colors.transparent, // 背景透明,以便自定义圆角
      builder: (context) {
        return Padding(
          padding: EdgeInsets.all(ScreenAdapter.width(20)), // 整体四周边距
          child: Container(
            width: ScreenAdapter.width(335),
            //height: ScreenAdapter.height(201),
            decoration: BoxDecoration(
              color: AppColors.colorFFFFFFFF,
              borderRadius: BorderRadius.circular(
                ScreenAdapter.radius(20),
              ), // 圆角
            ),
            // 内部内容边距
            child: Stack(
              children: [
                Padding(
                  padding: EdgeInsets.only(
                    left: ScreenAdapter.width(20),
                    right: ScreenAdapter.width(20),
                    bottom: ScreenAdapter.height(20),
                    top: ScreenAdapter.height(15),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min, // 根据内容高度自适应
                    children: [
                      Row(
                        mainAxisAlignment: .center,
                        children: [
                          Text(
                            '語言切換',
                            style: AppTextstyle.size18ColorFF000000Medium,
                          ),
                        ],
                      ),
                      child,
                    ],
                  ),
                ),
                Positioned(
                  top: ScreenAdapter.height(15),
                  right: ScreenAdapter.width(15),
                  child: Mygesturedetector(
                    onTap: () {
                      Navigator.pop(context);
                      onTap?.call();
                    },
                    child: Icon(
                      Icons.cancel_outlined,
                      size: ScreenAdapter.fontSize(20),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  /// Get弹窗
  static void showGetDialog(BuildContext context) {
    Get.dialog(
      Container(
        alignment: Alignment.center,
        margin: EdgeInsets.symmetric(
          vertical: ScreenAdapter.height(300),
          horizontal: ScreenAdapter.width(50),
        ),
        color: Colors.white,
        child: const Text("自定义内容"),
      ),
      transitionCurve: Curves.easeOutBack,
      transitionDuration: const Duration(milliseconds: 260),
    );
  }

  /// Get底部弹窗
  static void showGetBottomSheet(BuildContext context) {
    Get.bottomSheet(
      Container(
        width: ScreenAdapter.width(350),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16), // 圆角
        ),
        padding: const EdgeInsets.all(16), // 内部内容边距
        child: Column(
          mainAxisSize: MainAxisSize.min, // 根据内容高度自适应
          children: [
            const Text('这是底部弹框'),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text('关闭'),
            ),
          ],
        ),
      ),
    );
  }

  /// 完全自定义动画的对话框(showGeneralDialog)
  static void showMyGeneralDialog(BuildContext context) {
    showGeneralDialog(
      context: context,
      barrierDismissible: true,
      barrierLabel: "自定义弹窗",
      transitionDuration: const Duration(milliseconds: 300),
      pageBuilder: (context, animation, secondaryAnimation) {
        return Center(
          child: Container(
            width: 260,
            padding: const EdgeInsets.all(20),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(18),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Text("GeneralDialog 弹窗"),
                const SizedBox(height: 12),
                ElevatedButton(
                  onPressed: () => Navigator.pop(context),
                  child: const Text("关闭"),
                ),
              ],
            ),
          ),
        );
      },
      transitionBuilder: (context, anim, secAnim, child) {
        return Transform.scale(
          scale: anim.value,
          child: Opacity(opacity: anim.value, child: child),
        );
      },
    );
  }

  /// 系统应用信息弹窗(关于)
  static void showMyAboutDialog(BuildContext context) {
    showAboutDialog(
      context: context,
      applicationVersion: "1.0.0",
      applicationName: "Recruitment App",
      applicationLegalese: "© 2025 All rights reserved.",
    );
  }

  /// 时间选择器
  static Future<void> showMyTimePicker(BuildContext context) async {
    final TimeOfDay? result = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
    );

    print("选择时间: $result");
  }

  /// 日期选择器
  static Future<void> showMyDatePicker(BuildContext context) async {
    final DateTime? result = await showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime(2020),
      lastDate: DateTime(2030),
    );

    print("选择日期: $result");
  }

  /// 日期范围选择器
  static Future<void> showMyDateRangePicker(BuildContext context) async {
    final DateTimeRange? result = await showDateRangePicker(
      context: context,
      firstDate: DateTime(2020),
      lastDate: DateTime(2030),
      initialDateRange: DateTimeRange(
        start: DateTime.now(),
        end: DateTime.now().add(const Duration(days: 3)),
      ),
    );

    print("选择范围: $result");
  }

  /// 非模态 BottomSheet(可与页面交互)
  static void showMyBottomSheet(BuildContext context) {
    Scaffold.of(context).showBottomSheet(
      (context) => Container(
        padding: const EdgeInsets.all(16),
        height: 180,
        color: Colors.white,
        child: Column(
          children: [
            const Text("非模态 BottomSheet"),
            const SizedBox(height: 12),
            ElevatedButton(
              onPressed: () => Navigator.pop(context),
              child: const Text("关闭"),
            ),
          ],
        ),
      ),
    );
  }

  /// 弹出浮层菜单 showMenu
  static Future<void> showMyMenu(BuildContext context, Offset position) async {
    final result = await showMenu(
      context: context,
      position: RelativeRect.fromLTRB(
        position.dx,
        position.dy,
        position.dx + 1,
        position.dy + 1,
      ),
      items: [
        const PopupMenuItem(value: 1, child: Text("菜单 1")),
        const PopupMenuItem(value: 2, child: Text("菜单 2")),
      ],
    );

    print("选择菜单: $result");
  }

  /// iOS 风格弹窗
  static void showMyCupertinoDialog(BuildContext context) {
    showCupertinoDialog(
      context: context,
      builder: (context) => CupertinoAlertDialog(
        title: const Text("iOS 弹窗"),
        content: const Text("这是一个 iOS 风格的 AlertDialog"),
        actions: [
          CupertinoDialogAction(
            child: const Text("取消"),
            onPressed: () => Navigator.pop(context),
          ),
          CupertinoDialogAction(
            child: const Text("确定"),
            onPressed: () => Navigator.pop(context),
          ),
        ],
      ),
    );
  }

  /// iOS ActionSheet
  static void showMyCupertinoActionSheet(BuildContext context) {
    showCupertinoModalPopup(
      context: context,
      builder: (context) => CupertinoActionSheet(
        title: const Text("选择操作"),
        actions: [
          CupertinoActionSheetAction(
            onPressed: () => Navigator.pop(context),
            child: const Text("选项 1"),
          ),
          CupertinoActionSheetAction(
            onPressed: () => Navigator.pop(context),
            child: const Text("选项 2"),
          ),
        ],
        cancelButton: CupertinoActionSheetAction(
          onPressed: () => Navigator.pop(context),
          child: const Text("取消"),
        ),
      ),
    );
  }
}
class CountryChoiceView extends GetView<CountryChoiceController> {
  const CountryChoiceView({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('CountryChoiceView'), centerTitle: true),

      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /// ---------- 普通 Dialog ----------
            const Text(
              "➡ 普通 Dialog 弹窗",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(context, "AlertDialog", Mydialog.showAlertDialog),
            _buildBtn(context, "SimpleDialog", Mydialog.showSimpleDialog),
            _buildBtn(context, "自定义 Dialog(showDialog)", Mydialog.showMyDialog),

            const SizedBox(height: 20),

            /// ---------- BottomSheet ----------
            const Text(
              "➡ Bottom Sheet",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(
              context,
              "Modal BottomSheet",
              Mydialog.showMyModalBottomSheet,
            ),
            Builder(
              builder: (context) {
                return ElevatedButton(
                  child: Text("非模态 BottomSheet"),
                  onPressed: () {
                    Mydialog.showMyBottomSheet(context);
                  },
                );
              },
            ),
            const SizedBox(height: 20),

            /// ---------- GetX 弹窗 ----------
            const Text(
              "➡ GetX 弹窗",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(context, "Get.dialog", Mydialog.showGetDialog),
            _buildBtn(context, "Get.bottomSheet", Mydialog.showGetBottomSheet),

            const SizedBox(height: 20),

            /// ---------- 高级  showGeneralDialog ----------
            const Text(
              "➡ 自定义动画 Dialog(showGeneralDialog)",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(
              context,
              "showGeneralDialog",
              Mydialog.showMyGeneralDialog,
            ),

            const SizedBox(height: 20),

            /// ---------- 时间日期 ----------
            const Text(
              "➡ 日期 / 时间 Picker",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(context, "TimePicker", Mydialog.showMyTimePicker),
            _buildBtn(context, "DatePicker", Mydialog.showMyDatePicker),
            _buildBtn(
              context,
              "DateRangePicker",
              Mydialog.showMyDateRangePicker,
            ),

            const SizedBox(height: 20),

            /// ---------- 菜单 ----------
            const Text(
              "➡ 浮层菜单 showMenu",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            ElevatedButton(
              onPressed: () async {
                RenderBox box = context.findRenderObject() as RenderBox;
                Offset position = box.localToGlobal(Offset.zero);
                Mydialog.showMyMenu(context, position);
              },
              child: const Text("showMenu"),
            ),

            const SizedBox(height: 20),

            /// ---------- About ----------
            const Text(
              "➡ 关于弹窗 AboutDialog",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(context, "AboutDialog", Mydialog.showMyAboutDialog),

            const SizedBox(height: 20),

            /// ---------- Cupertino ----------
            const Text(
              "➡ iOS 弹窗",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            _buildBtn(
              context,
              "CupertinoAlertDialog",
              Mydialog.showMyCupertinoDialog,
            ),
            _buildBtn(
              context,
              "CupertinoActionSheet",
              Mydialog.showMyCupertinoActionSheet,
            ),

            const SizedBox(height: 40),
          ],
        ),
      ),
    );
  }

  /// 通用按钮组件
  Widget _buildBtn(
    BuildContext context,
    String text,
    Function(BuildContext) onTap,
  ) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6),
      child: ElevatedButton(onPressed: () => onTap(context), child: Text(text)),
    );
  }
}