pannel_animation.dart 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import 'package:flutter/material.dart';
  2. class AnimatedPanel extends StatefulWidget {
  3. final bool isClosed;
  4. final double closedX;
  5. final double closedY;
  6. final double duration;
  7. final Curve? curve;
  8. final Widget? child;
  9. const AnimatedPanel(
  10. {Key? key,
  11. this.isClosed = false,
  12. this.closedX = 0.0,
  13. this.closedY = 0.0,
  14. this.duration = 0.0,
  15. this.curve,
  16. this.child})
  17. : super(key: key);
  18. @override
  19. _AnimatedPanelState createState() => _AnimatedPanelState();
  20. }
  21. class _AnimatedPanelState extends State<AnimatedPanel> {
  22. bool _isHidden = true;
  23. @override
  24. Widget build(BuildContext context) {
  25. Offset closePos = Offset(widget.closedX, widget.closedY);
  26. double duration = _isHidden && widget.isClosed ? 0 : widget.duration;
  27. return TweenAnimationBuilder(
  28. curve: widget.curve ?? Curves.easeOut,
  29. tween: Tween<Offset>(
  30. begin: !widget.isClosed ? Offset.zero : closePos,
  31. end: !widget.isClosed ? Offset.zero : closePos,
  32. ),
  33. duration: Duration(milliseconds: (duration * 1000).round()),
  34. builder: (_, Offset value, Widget? c) {
  35. _isHidden =
  36. widget.isClosed && value == Offset(widget.closedX, widget.closedY);
  37. return _isHidden
  38. ? Container()
  39. : Transform.translate(offset: value, child: c);
  40. },
  41. child: widget.child,
  42. );
  43. }
  44. }
  45. extension AnimatedPanelExtensions on Widget {
  46. Widget animatedPanelX(
  47. {double closeX = 0.0,
  48. bool? isClosed,
  49. double? duration,
  50. Curve? curve}) =>
  51. animatedPanel(
  52. closePos: Offset(closeX, 0),
  53. isClosed: isClosed,
  54. curve: curve,
  55. duration: duration);
  56. Widget animatedPanelY(
  57. {double closeY = 0.0,
  58. bool? isClosed,
  59. double? duration,
  60. Curve? curve}) =>
  61. animatedPanel(
  62. closePos: Offset(0, closeY),
  63. isClosed: isClosed,
  64. curve: curve,
  65. duration: duration);
  66. Widget animatedPanel(
  67. {required Offset closePos,
  68. bool? isClosed,
  69. double? duration,
  70. Curve? curve}) {
  71. return AnimatedPanel(
  72. closedX: closePos.dx,
  73. closedY: closePos.dy,
  74. child: this,
  75. isClosed: isClosed ?? false,
  76. duration: duration ?? .35,
  77. curve: curve);
  78. }
  79. }