import 'package:flutter/material.dart'; /// 按钮样式类型 enum ButtonStyleType { primary, // 主样式:纯色背景,无边框 secondary, // 次样式:白色背景,深灰文字,深灰边框 } /// 自定义默认按钮(支持不可点击/禁用状态和防连点功能) class CustomButton extends StatefulWidget { final String text; // 按钮文字 final Color backgroundColor; // 按钮背景色 final double borderRadius; // 圆角半径(默认5) final VoidCallback? onPressed; // 点击事件回调 final EdgeInsetsGeometry? padding; // 内边距 final EdgeInsetsGeometry? margin; // 外边距 final double? height; // 按钮高度 final TextStyle? textStyle; // 文字样式 /// 新增:是否可点击(true 可点,false 禁用) /// 注意:如果 onPressed 为 null,也会被视为不可点击 final bool enabled; /// 新增:禁用时的背景色(可选) final Color? disabledBackgroundColor; /// 新增:禁用时的文字颜色(可选) final Color? disabledTextColor; /// 新增:文字颜色(可选) final Color? textColor; /// 新增:防连点间隔时间(毫秒) final int debounceInterval; /// 新增:按钮样式类型 final ButtonStyleType buttonStyle; /// 新增:边框颜色(仅在 secondary 样式下使用,如不指定则使用默认深灰色) final Color? borderColor; /// 新增:边框宽度(仅在 secondary 样式下使用) final double borderWidth; const CustomButton({ super.key, required this.text, this.backgroundColor = Colors.blue, this.borderRadius = 5.0, this.onPressed, this.padding, this.margin, this.height, this.textStyle, this.textColor, this.enabled = true, this.disabledBackgroundColor, this.disabledTextColor, this.debounceInterval = 1000, // 默认1秒防连点 this.buttonStyle = ButtonStyleType.primary, // 默认为主样式 this.borderColor, this.borderWidth = 1.0, }); @override State createState() => _CustomButtonState(); } class _CustomButtonState extends State { // 记录最后一次点击时间 DateTime _lastClickTime = DateTime(0); @override Widget build(BuildContext context) { // 如果 enabled 为 false 或 onPressed 为 null,则视为不可点击 final bool isEnabled = widget.enabled && widget.onPressed != null; // 根据按钮样式计算背景色、文字颜色和边框 final Color bgColor; final Color textColor; final Color? borderColor; if (widget.buttonStyle == ButtonStyleType.secondary) { // 次样式:白色背景,深灰文字,深灰边框 bgColor = isEnabled ? Colors.white : (widget.disabledBackgroundColor ?? Colors.grey.shade200); textColor = isEnabled ? Colors.grey[800]! : (widget.disabledTextColor ?? Colors.grey.shade500); borderColor = isEnabled ? (widget.borderColor ?? Colors.grey.shade400) : (widget.disabledTextColor ?? Colors.grey.shade300); } else { // 主样式:原有逻辑 bgColor = isEnabled ? widget.backgroundColor : (widget.disabledBackgroundColor ?? Colors.grey.shade400); textColor = widget.textColor ?? (isEnabled ? Colors.white : (widget .disabledTextColor ?? Colors.white70)); borderColor = null; // 主样式默认无边框 } // 计算最终文字样式 TextStyle finalTextStyle; if (widget.textStyle != null) { finalTextStyle = widget.textStyle!.copyWith(color: textColor); } else { finalTextStyle = TextStyle( color: textColor, fontSize: 14, fontWeight: FontWeight.bold, ); } // 处理点击事件(添加防连点逻辑) void handleOnPressed() { final now = DateTime.now(); if (now .difference(_lastClickTime) .inMilliseconds < widget.debounceInterval) { // 在防连点间隔内,不执行操作 return; } _lastClickTime = now; if (widget.onPressed != null) { widget.onPressed!(); } } // 构建边框 final BoxBorder? border = borderColor != null ? Border.all( color: borderColor, width: widget.borderWidth, ) : null; // 点击拦截器 + 视觉反馈(禁用时降低不透明度) return Opacity( opacity: isEnabled ? 1.0 : 0.65, child: AbsorbPointer( absorbing: !isEnabled, child: GestureDetector( onTap: isEnabled ? handleOnPressed : null, child: Container( height: widget.height ?? 45, // 默认高度45 padding: widget.padding ?? const EdgeInsets.all(6), // 默认内边距 margin: widget.margin ?? const EdgeInsets.symmetric(horizontal: 5), // 默认外边距 decoration: BoxDecoration( borderRadius: BorderRadius.circular(widget.borderRadius), color: bgColor, border: border, ), child: Center( child: Text( widget.text, style: finalTextStyle, ), ), ), ), ), ); } }