import 'package:cs_resources/generated/assets.dart'; import 'package:flutter/material.dart'; import 'package:cs_resources/generated/l10n.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared/utils/log_utils.dart'; import 'package:widgets/ext/ex_widget.dart'; import 'package:cs_resources/theme/app_colors_theme.dart'; import 'package:widgets/my_text_view.dart'; import 'package:widgets/no_shadow_scroll_behavior.dart'; import 'package:widgets/widget_export.dart'; import '../load_state_layout.dart'; import '../my_load_image.dart'; ///四种视图状态 // enum DialogLoadingState { State_Success, State_Error, State_Loading, State_Empty } /* * 弹窗内容的包装组件 * 弹框内容自定义传入 messageBuilder */ class DialogContentWrap extends StatefulWidget { LoadState? loadingState; String? title; Widget Function(BuildContext)? titleBuilder; String? message; Widget Function(BuildContext)? messageBuilder; VoidCallback confirmAction; VoidCallback? cancelAction; bool isShowConfirmBtn; bool isShowCancelBtn; Widget Function(BuildContext)? bottomFooterBuilder; // 自定义底部按钮区 bool showCloseIcon; String? confirmTxt; String? cancelTxt; TextStyle? titleTextStyle; Color? titleBackgroundColor; Color? backgroundColor; Color? noBtnBg; Color? yesBtnBg; Color? closeIconColor; TextStyle? yesBtnTextStyle; TextStyle? noBtnTextStyle; double? bottomBtnRadius; EdgeInsets? bottomBtnSectionPadding; EdgeInsets? contentPadding; final double? bottomBtnSpace; final double? topLeftRadius; final double? topRightRadius; final double? bottomRightRadius; final double? bottomLeftRadius; final double? minHeight; final double? maxHeight; final double? dialogWidth; DialogContentWrap({ Key? key, this.loadingState = LoadState.State_Loading, this.title, this.message, Widget Function(BuildContext)? this.titleBuilder, Widget Function(BuildContext)? this.messageBuilder, Widget Function(BuildContext)? this.bottomFooterBuilder, required this.confirmAction, this.cancelAction, this.showCloseIcon = true, this.isShowConfirmBtn = true, this.isShowCancelBtn = true, this.confirmTxt, this.cancelTxt, this.titleTextStyle, this.titleBackgroundColor = Colors.white, this.backgroundColor = Colors.white, this.closeIconColor = Colors.white, this.bottomBtnRadius = 7, this.noBtnBg, this.yesBtnBg, this.yesBtnTextStyle, this.noBtnTextStyle, this.bottomBtnSectionPadding, this.contentPadding = const EdgeInsets.only( left: 0, right: 0, bottom: 0, top: 0), this.bottomBtnSpace = 0, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, minHeight, maxHeight, dialogWidth, }) : minHeight = minHeight ?? 0, maxHeight = maxHeight ?? 300, dialogWidth = dialogWidth ?? 300.0, topLeftRadius = topLeftRadius ?? 0, topRightRadius = topRightRadius ?? 0, bottomLeftRadius = bottomLeftRadius ?? 0, bottomRightRadius = bottomRightRadius ?? 0, super(key: key); @override DialogContentWrapState createState() => DialogContentWrapState(); } class DialogContentWrapState extends State { @override void initState() { super.initState(); } // 修改 dialogLoadingState void changeDialogLoadingState(LoadState state){ Log.d("change loadState"); setState(() { widget.loadingState = state; }); } @override Widget build(BuildContext context) { Log.d("dialogWidth ${widget.dialogWidth} "); double _dialogWidth = widget.dialogWidth?? MediaQuery.of(context).size.width * 0.65; bool _showTitleSection = (widget.title != null && widget.title!.isNotEmpty) || widget.titleBuilder != null; bool _showBottomBtnSection = widget.isShowConfirmBtn || widget.isShowCancelBtn || widget.bottomFooterBuilder != null; double _bottomBtnSectionHeight = _showBottomBtnSection ? 50 : 0; double _scrollMaxHeight = widget.maxHeight! - _bottomBtnSectionHeight; double _bottomBtnMargin = 0; String _errorMessage = 'Data loading failed! Please refresh and try again'; if(widget.isShowConfirmBtn && widget.isShowCancelBtn){ _bottomBtnMargin = widget.bottomBtnSpace??0/2; } return Stack( children: [ ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(widget.topLeftRadius!), topRight: Radius.circular(widget.topRightRadius!), bottomLeft: Radius.circular(widget.bottomLeftRadius!), bottomRight: Radius.circular(widget.bottomRightRadius!), ), child: Container( width: _dialogWidth, constraints: BoxConstraints( minHeight: widget.minHeight!, maxHeight: widget.maxHeight!, ), decoration: BoxDecoration( color: widget.backgroundColor?? context.appColors.whiteBG, // borderRadius: BorderRadius.only( // topLeft: Radius.circular(topLeftRadius!), // topRight: Radius.circular(topRightRadius!), // ), ), child: LoadStateLayout( state: widget.loadingState??LoadState.State_Loading, errorMessage: _errorMessage, errorRetry: () { }, successWidget: Column( children: [ // 标题区 Container( width: double.infinity, color: widget.titleBackgroundColor, child: Visibility( visible: _showTitleSection, child: (widget.title != null && widget.title!.isNotEmpty)? MyTextView( widget.title ?? '', fontSize: 18, isFontMedium: true, textColor: widget.titleTextStyle?.color ?? context.appColors.textBlack, paddingTop: 15, paddingBottom: 15, textAlign: TextAlign.center, textStyle: widget.titleTextStyle, ): widget.titleBuilder!.call(context), ), ), // 内容区 Expanded( child: Scrollbar( child: ScrollConfiguration( behavior: NoShadowScrollBehavior(), child: SingleChildScrollView( child: Container( width: double.infinity, padding: widget.contentPadding, child: widget.messageBuilder?.call(context) ?? MyTextView( widget.message!, fontSize: 18, textColor: context.appColors.textBlack, isFontRegular: true, textAlign: TextAlign.center, ), ), ), ), ).constrained(maxHeight: _scrollMaxHeight), ), // 底部按钮区 Visibility( visible: _showBottomBtnSection, child: (widget.isShowCancelBtn || widget.isShowConfirmBtn)? Container( height: _bottomBtnSectionHeight, color: context.appColors.whiteBG, padding: widget.bottomBtnSectionPadding, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Visibility( visible: widget.isShowCancelBtn, child: Expanded( flex: 1, child: InkWell( onTap: () { onCancel(); widget.cancelAction?.call(); }, child: MyTextView( widget.cancelTxt ?? S.current.no, fontSize: 16, isFontMedium: true, paddingTop: 13, paddingBottom: 13, textAlign: TextAlign.center, textColor: context.appColors.whiteBG, backgroundColor: widget.noBtnBg ?? context.appColors.orangeBG, cornerRadius: widget.bottomBtnRadius ?? 0, textStyle: widget.noBtnTextStyle, ), )), ), SizedBox( width: _bottomBtnMargin, ), Visibility( visible: widget.isShowConfirmBtn, child: Expanded( flex: 1, child: InkWell( onTap: () async { onCancel(); widget.confirmAction(); }, child: MyTextView( widget.confirmTxt ?? S.current.yes, fontSize: 16, paddingTop: 13, paddingBottom: 13, isFontMedium: true, textAlign: TextAlign.center, textColor: Colors.white, backgroundColor: widget.yesBtnBg?? context.appColors.btnBgDefault, cornerRadius: widget.bottomBtnRadius ?? 0, textStyle: widget.yesBtnTextStyle, ), )), ), ], ), ): Container( child: widget.bottomFooterBuilder?.call(context), ), ), ], ), ), ), ), // 右上角 关闭按钮 Visibility( visible: widget.showCloseIcon, child: Positioned( top: 0, right: 0, child: MyAssetImage( Assets.baseServiceDialogDeleteIcon, width: 25, height: 25.5, color: widget.closeIconColor ?? context.appColors.textPrimary, ).onTap((){ onCancel(); },padding: 10), ), ) ], ); } //取消弹框 void onCancel() async { SmartDialog.dismiss(); } }