animated_visibility.dart 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import 'package:flutter/material.dart';
  2. class AnimatedVisibility extends StatefulWidget {
  3. final bool visible;
  4. final Widget child;
  5. final Duration duration;
  6. final Curve curve;
  7. const AnimatedVisibility({
  8. super.key,
  9. required this.visible,
  10. required this.child,
  11. this.duration = const Duration(milliseconds: 400),
  12. this.curve = Curves.easeInOut,
  13. });
  14. @override
  15. State<AnimatedVisibility> createState() => _AnimatedVisibilityState();
  16. }
  17. class _AnimatedVisibilityState extends State<AnimatedVisibility>
  18. with SingleTickerProviderStateMixin {
  19. late final AnimationController _controller;
  20. late final Animation<double> _fadeAnimation;
  21. @override
  22. void initState() {
  23. super.initState();
  24. _controller = AnimationController(
  25. duration: widget.duration,
  26. vsync: this,
  27. );
  28. _fadeAnimation = CurvedAnimation(parent: _controller, curve: widget.curve);
  29. if (widget.visible) {
  30. _controller.forward();
  31. }
  32. }
  33. @override
  34. void didUpdateWidget(covariant AnimatedVisibility oldWidget) {
  35. super.didUpdateWidget(oldWidget);
  36. if (widget.visible != oldWidget.visible) {
  37. widget.visible ? _controller.forward() : _controller.reverse();
  38. }
  39. }
  40. @override
  41. void dispose() {
  42. _controller.dispose();
  43. super.dispose();
  44. }
  45. @override
  46. Widget build(BuildContext context) {
  47. return SizeTransition(
  48. sizeFactor: _fadeAnimation,
  49. axisAlignment: -1.0, // 从上方展开
  50. child: FadeTransition(
  51. opacity: _fadeAnimation,
  52. child: widget.child,
  53. ),
  54. );
  55. }
  56. }