chatapp3-flutter/lib/ui_kit/widgets/sc_lk_tap_widget.dart
2026-04-09 21:32:23 +08:00

108 lines
2.6 KiB
Dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class SCLkTapWidget extends StatefulWidget {
final Widget? child;
final Function? onTap;
Color highlightColor;
final Duration? duration;
final BorderRadius? borderRadius;
SCLkTapWidget(
{Key? key,
this.child,
this.onTap,
this.highlightColor = Colors.black12,
this.duration, this.borderRadius})
: super(key: key);
@override
TapWidgetState createState() {
return new TapWidgetState();
}
}
class TapWidgetState extends State<SCLkTapWidget>
with SingleTickerProviderStateMixin {
late AnimationController _ctl;
late Animation<Color> _colorAnimation;
Duration? _duration;
bool get onTapEnable => widget.onTap != null;
@override
void initState() {
super.initState();
_duration = widget.duration;
if (_duration == null) {
_duration = Duration(milliseconds: 1);
}
_ctl = AnimationController(vsync: this, duration: _duration);
widget.highlightColor??=Colors.black12;
_colorAnimation = Tween<Color>(
begin: widget.highlightColor.withOpacity(0.0),
end: widget.highlightColor,
).animate(_ctl);
}
@override
void dispose() {
_ctl.stop();
_ctl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: AnimatedBuilder(
animation: _ctl,
builder: (BuildContext context, Widget? child) {
return Container(
foregroundDecoration: BoxDecoration(
color: _colorAnimation.value,
borderRadius: widget.borderRadius
),
child: widget.child,
);
},
),
onTap: (){
if(widget.onTap!=null){
widget.onTap!();
}
},
onTapDown: (d) {
if (onTapEnable) _ctl.forward();
},
onTapUp: (d) {
if (onTapEnable) prepareToIdle();
},
onTapCancel: (){
if (onTapEnable) prepareToIdle();
},
);
}
void prepareToIdle() {
late AnimationStatusListener listener;
listener = (AnimationStatus statue) {
if (statue == AnimationStatus.completed) {
_ctl.removeStatusListener(listener);
toStart();
}
};
_ctl.addStatusListener(listener);
if (!_ctl.isAnimating) {
_ctl.removeStatusListener(listener);
toStart();
}
}
void toStart() {
_ctl.stop();
_ctl.reverse();
}
}