import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; class HIDialog extends StatefulWidget { final String? title; final String? message; final String? confirmText; final String? cancelText; final VoidCallback? onConfirm; final VoidCallback? onCancel; final Widget? customMessageWidget; /// 是否允许点击外部关闭 final bool barrierDismissible; /// 是否禁止物理返回键关闭 final bool preventBackDismiss; /// 是否点击确认后自动关闭(默认 true) final bool autoClose; /// 是否显示按钮 loading(autoClose=false 时自动启用) final bool? showLoading; const HIDialog({ Key? key, this.title, this.message, this.confirmText, this.cancelText, this.onConfirm, this.onCancel, this.customMessageWidget, this.barrierDismissible = true, this.preventBackDismiss = false, this.autoClose = true, this.showLoading, }) : super(key: key); static Future show({ String? title, String? message, String? confirmText, String? cancelText, VoidCallback? onConfirm, VoidCallback? onCancel, Widget? customMessageWidget, bool barrierDismissible = true, bool preventBackDismiss = false, bool autoClose = true, bool? showLoading, }) { return Get.dialog( HIDialog( title: title, message: message, confirmText: confirmText, cancelText: cancelText, onConfirm: onConfirm, onCancel: onCancel, customMessageWidget: customMessageWidget, barrierDismissible: barrierDismissible, preventBackDismiss: preventBackDismiss, autoClose: autoClose, showLoading: showLoading, ), barrierDismissible: barrierDismissible, barrierColor: Colors.transparent, ); } @override State createState() => _HIDialogState(); } class _HIDialogState extends State { bool _isLoading = false; Future _handleConfirm() async { if (_isLoading) return; final useLoading = widget.showLoading ?? !widget.autoClose; if (useLoading) { setState(() => _isLoading = true); } if (widget.autoClose) { Get.back(); } await Future.microtask(() => widget.onConfirm?.call()); if (useLoading && mounted) { setState(() => _isLoading = false); } } Widget _buildConfirmButton() { return TextButton( onPressed: _isLoading ? null : _handleConfirm, style: TextButton.styleFrom( backgroundColor: const Color(0xFFADFF5B), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(23.r), ), minimumSize: Size(85.w, 40.w), padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: _isLoading ? SizedBox( height: 20.w, width: 20.w, child: const CircularProgressIndicator( color: Colors.black, strokeWidth: 2, ), ) : Text( widget.confirmText ?? (widget.cancelText == null ? '好的' : AppTranslations.kr_dialog.kr_confirm), style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.black, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ); } @override Widget build(BuildContext context) { final dialog = Dialog( backgroundColor: Colors.transparent, insetPadding: EdgeInsets.all(20.w), child: Transform.translate( offset: Offset(0, -30.w), child: ClipRRect( borderRadius: BorderRadius.circular(34.r), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 26, sigmaY: 26), // 毛玻璃模糊 child: Container( width: 245.w, padding: EdgeInsets.fromLTRB(30.w, 16.w, 30.w, 16.w), decoration: BoxDecoration( color: const Color(0xFFDEDEDE), // 半透明底色 borderRadius: BorderRadius.circular(34.r), border: Border.all( color: Colors.white.withOpacity(0.2), // 高光边框 width: 1.5, ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ if (widget.title != null) ...[ Align( alignment: Alignment.centerLeft, child: Text( widget.title!, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.black, height: 1.3, ), ), ), SizedBox(height: 4.w), ], if (widget.message != null || widget.customMessageWidget != null) ...[ Container( constraints: BoxConstraints(maxHeight: 200.h), child: SingleChildScrollView( child: widget.customMessageWidget ?? Text( widget.message!, textAlign: TextAlign.left, style: TextStyle( fontSize: 14.sp, color: Colors.black, height: 1.4, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ), ), ], if (widget.confirmText != null || widget.cancelText != null || (widget.confirmText == null && widget.cancelText == null)) ...[ SizedBox(height: 12.w), if (widget.confirmText == null && widget.cancelText == null) Center( child: SizedBox( width: 85.w, child: _buildConfirmButton(), ), ) else Row( children: [ if (widget.confirmText != null) Expanded(child: _buildConfirmButton()), if (widget.cancelText != null && widget.confirmText != null) SizedBox(width: 12.w), if (widget.cancelText != null) Expanded( child: TextButton( onPressed: () { Get.back(); widget.onCancel?.call(); }, style: TextButton.styleFrom( backgroundColor: const Color(0xFFFF00B7), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(23.r), ), minimumSize: Size(85.w, 40.w), padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: Text( widget.cancelText!, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.black, fontFamily: 'AlibabaPuHuiTi-Medium', ), ), ), ), ], ), ] ], ), ), ), ), ), ); if (widget.preventBackDismiss) { return WillPopScope(onWillPop: () async => false, child: dialog); } return dialog; } }