repeat_tween_animation_builder.dart 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import 'package:flutter/material.dart';
  2. /// 由 [TweenAnimationBuilder] 改造的组件,区别在于这个会重复动画。
  3. class RepeatTweenAnimationBuilder<T extends Object?> extends ImplicitlyAnimatedWidget {
  4. const RepeatTweenAnimationBuilder({
  5. super.key,
  6. required this.tween,
  7. required super.duration,
  8. super.curve,
  9. required this.builder,
  10. super.onEnd,
  11. this.child,
  12. });
  13. final Tween<T> tween;
  14. final ValueWidgetBuilder<T> builder;
  15. final Widget? child;
  16. @override
  17. ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() {
  18. return _TweenAnimationBuilderState<T>();
  19. }
  20. }
  21. class _TweenAnimationBuilderState<T extends Object?> extends AnimatedWidgetBaseState<RepeatTweenAnimationBuilder<T>> {
  22. Tween<T>? _currentTween;
  23. @override
  24. void initState() {
  25. _currentTween = widget.tween;
  26. _currentTween!.begin ??= _currentTween!.end;
  27. super.initState();
  28. if (_currentTween!.begin != _currentTween!.end) {
  29. // 使用 repeat 来重复绘制动画。
  30. controller.repeat(reverse: true);
  31. }
  32. }
  33. @override
  34. void forEachTween(TweenVisitor<dynamic> visitor) {
  35. assert(
  36. widget.tween.end != null,
  37. 'Tween provided to TweenAnimationBuilder must have non-null Tween.end value.',
  38. );
  39. _currentTween = visitor(_currentTween, widget.tween.end, (dynamic value) {
  40. assert(false);
  41. throw StateError('Constructor will never be called because null is never provided as current tween.');
  42. }) as Tween<T>?;
  43. }
  44. @override
  45. Widget build(BuildContext context) {
  46. return widget.builder(context, _currentTween!.evaluate(animation), widget.child);
  47. }
  48. }