import 'package:flutter/material.dart'; class CustomCard extends StatefulWidget { final double borderRadius; // 圆角 final VoidCallback onTap; // 点击回调 final List colors; // 背景颜色列表 final Widget child; // 子组件 final String title; const CustomCard({ Key? key, required this.borderRadius, required this.onTap, required this.colors, required this.child, required this.title, }) : super(key: key); @override State createState() => _CustomCardState(); } class _CustomCardState extends State with SingleTickerProviderStateMixin { double _scale = 1.0; final Duration _animationDuration = Duration(milliseconds: 50); final GlobalKey _inkKey = GlobalKey(); Future _handleTap(TapDownDetails details) async { setState(() { _scale = 0.95; }); await Future.delayed(_animationDuration); setState(() { _scale = 1.0; }); await Future.delayed(_animationDuration); // 手动触发水波纹 final RenderBox? box = _inkKey.currentContext?.findRenderObject() as RenderBox?; if (box != null) { final Offset localPosition = box.globalToLocal(details.globalPosition); InkRipple.splashFactory.create( controller: Material.of(_inkKey.currentContext!)!, referenceBox: box, position: localPosition, color: widget.colors.first.withOpacity(0.2), containedInkWell: true, borderRadius: BorderRadius.circular(widget.borderRadius), textDirection: Directionality.of(context), ); } widget.onTap(); } @override Widget build(BuildContext context) { final bool isGradient = widget.colors.length > 1; final Color baseColor = widget.colors.first; return Material( color: Colors.transparent, borderRadius: BorderRadius.circular(widget.borderRadius), child: GestureDetector( onTapDown: _handleTap, behavior: HitTestBehavior.translucent, // 关键:让空白区域也能点击 child: AnimatedScale( scale: _scale, duration: _animationDuration, curve: Curves.easeInOut, child: Ink( key: _inkKey, decoration: BoxDecoration( color: isGradient ? null : baseColor, gradient: isGradient ? LinearGradient( colors: widget.colors, begin: Alignment.topLeft, end: Alignment.bottomRight, ) : null, borderRadius: BorderRadius.circular(widget.borderRadius), ), child: widget.child, ), ), ), ); } }