flutter_integrated_whb/lib/customWidget/custom_button.dart

117 lines
3.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:flutter/material.dart';
/// 自定义默认按钮(支持不可点击/禁用状态和防连点功能)
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 int debounceInterval;
const CustomButton({
super.key,
required this.text,
required this.backgroundColor,
this.borderRadius = 5.0,
this.onPressed,
this.padding,
this.margin,
this.height,
this.textStyle,
this.enabled = true,
this.disabledBackgroundColor,
this.disabledTextColor,
this.debounceInterval = 1000, // 默认1秒防连点
});
@override
State<CustomButton> createState() => _CustomButtonState();
}
class _CustomButtonState extends State<CustomButton> {
// 记录最后一次点击时间
DateTime _lastClickTime = DateTime(0);
@override
Widget build(BuildContext context) {
// 如果 enabled 为 false 或 onPressed 为 null则视为不可点击
final bool isEnabled = widget.enabled && widget.onPressed != null;
// 计算展示用背景色与文字样式
final Color bgColor = isEnabled
? widget.backgroundColor
: (widget.disabledBackgroundColor ?? Colors.grey.shade400);
TextStyle finalTextStyle;
if (widget.textStyle != null) {
finalTextStyle = isEnabled
? widget.textStyle!
: widget.textStyle!.copyWith(
color: widget.disabledTextColor ?? widget.textStyle!.color?.withOpacity(0.8) ?? Colors.white70,
);
} else {
finalTextStyle = TextStyle(
color: isEnabled ? Colors.white : (widget.disabledTextColor ?? Colors.white70),
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!();
}
}
// 点击拦截器 + 视觉反馈(禁用时降低不透明度)
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,
),
child: Center(
child: Text(
widget.text,
style: finalTextStyle,
),
),
),
),
),
);
}
}