click_opacity.dart 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import 'package:flutter/material.dart';
  2. import 'package:nomo/app/extensions/widget_extension.dart';
  3. import 'package:nomo/utils/misc.dart';
  4. class ClickOpacity extends StatefulWidget {
  5. final Widget child;
  6. final VoidCallback? onTap;
  7. final VoidCallback? onLongPress;
  8. final double opacity;
  9. final Duration duration;
  10. final bool disabled;
  11. final bool disableFeedback;
  12. const ClickOpacity({
  13. super.key,
  14. required this.child,
  15. this.onTap,
  16. this.onLongPress,
  17. this.opacity = 0.5,
  18. this.duration = const Duration(milliseconds: 100),
  19. this.disabled = false,
  20. this.disableFeedback = false,
  21. });
  22. @override
  23. State<ClickOpacity> createState() => _ClickOpacityState();
  24. }
  25. class _ClickOpacityState extends State<ClickOpacity> {
  26. bool _isPressed = false;
  27. @override
  28. Widget build(BuildContext context) {
  29. return GestureDetector(
  30. behavior: HitTestBehavior.opaque,
  31. onTapDown: widget.disableFeedback || widget.disabled
  32. ? null
  33. : (_) => _setPressed(true),
  34. onTapUp: widget.disableFeedback || widget.disabled
  35. ? null
  36. : (_) => _setPressed(false),
  37. onTapCancel: widget.disableFeedback || widget.disabled
  38. ? null
  39. : () => _setPressed(false),
  40. onTap: widget.disabled ? null : widget.onTap,
  41. onLongPress: widget.disabled ? null : widget.onLongPress,
  42. child: AnimatedOpacity(
  43. opacity: _isPressed ? widget.opacity : 1.0,
  44. duration: widget.duration,
  45. child: widget.child,
  46. ),
  47. ).withClickCursor(!widget.disableFeedback && isDesktop);
  48. }
  49. void _setPressed(bool value) {
  50. if (mounted && _isPressed != value) {
  51. setState(() {
  52. _isPressed = value;
  53. });
  54. }
  55. }
  56. }