Unverified Commit 3bc906d3 authored by matthew-carroll's avatar matthew-carroll Committed by GitHub

Extracted an ImplicitlyAnimatedWidgetState from AnimatedWidgetBaseState (#18181)

Extracted a superclass from AnimatedWidgetBaseState that is called ImplicitlyAnimatedWidgetState. ImplicitlyAnimatedWidgetState implicitly animates, but it does not call setState() automatically. Subclasses must respond to animation changes themselves. This is a useful optimization for Widgets whose render objects listen to animations directly. (#18173)
parent 3b9b5ace
...@@ -210,7 +210,7 @@ abstract class ImplicitlyAnimatedWidget extends StatefulWidget { ...@@ -210,7 +210,7 @@ abstract class ImplicitlyAnimatedWidget extends StatefulWidget {
final Duration duration; final Duration duration;
@override @override
AnimatedWidgetBaseState<ImplicitlyAnimatedWidget> createState(); ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState();
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
...@@ -230,10 +230,17 @@ typedef Tween<T> TweenVisitor<T>(Tween<T> tween, T targetValue, TweenConstructor ...@@ -230,10 +230,17 @@ typedef Tween<T> TweenVisitor<T>(Tween<T> tween, T targetValue, TweenConstructor
/// A base class for widgets with implicit animations. /// A base class for widgets with implicit animations.
/// ///
/// Subclasses must implement the [forEachTween] method to help /// [ImplicitlyAnimatedWidgetState] requires that subclasses respond to the
/// [AnimatedWidgetBaseState] iterate through the subclasses' widget's fields /// animation, themselves. If you would like `setState()` to be called
/// and animate them. /// automatically as the animation changes, use [AnimatedWidgetBaseState].
abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> extends State<T> with SingleTickerProviderStateMixin { ///
/// Subclasses must implement the [forEachTween] method to allow
/// [ImplicitlyAnimatedWidgetState] to iterate through the subclasses' widget's
/// fields and animate them.
abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> extends State<T> with SingleTickerProviderStateMixin {
/// The animation controller driving this widget's implicit animations.
@protected
AnimationController get controller => _controller;
AnimationController _controller; AnimationController _controller;
/// The animation driving this widget's implicit animations. /// The animation driving this widget's implicit animations.
...@@ -247,7 +254,7 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten ...@@ -247,7 +254,7 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten
duration: widget.duration, duration: widget.duration,
debugLabel: '${widget.toStringShort()}', debugLabel: '${widget.toStringShort()}',
vsync: this, vsync: this,
)..addListener(_handleAnimationChanged); );
_updateCurve(); _updateCurve();
_constructTweens(); _constructTweens();
} }
...@@ -282,10 +289,6 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten ...@@ -282,10 +289,6 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten
super.dispose(); super.dispose();
} }
void _handleAnimationChanged() {
setState(() { });
}
bool _shouldAnimateTween(Tween<dynamic> tween, dynamic targetValue) { bool _shouldAnimateTween(Tween<dynamic> tween, dynamic targetValue) {
return targetValue != (tween.end ?? tween.begin); return targetValue != (tween.end ?? tween.begin);
} }
...@@ -331,6 +334,28 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten ...@@ -331,6 +334,28 @@ abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> exten
void forEachTween(TweenVisitor<dynamic> visitor); void forEachTween(TweenVisitor<dynamic> visitor);
} }
/// A base class for widgets with implicit animations that need to rebuild their
/// widget tree as the animation runs.
///
/// This class calls [build] each frame that the animation tickets. For a
/// variant that does not rebuild each frame, consider subclassing
/// [ImplicitlyAnimatedWidgetState] directly.
///
/// Subclasses must implement the [forEachTween] method to allow
/// [AnimatedWidgetBaseState] to iterate through the subclasses' widget's fields
/// and animate them.
abstract class AnimatedWidgetBaseState<T extends ImplicitlyAnimatedWidget> extends ImplicitlyAnimatedWidgetState<T> {
@override
void initState() {
super.initState();
controller.addListener(_handleAnimationChanged);
}
void _handleAnimationChanged() {
setState(() { /* The animation ticked. Rebuild with new animation value */ });
}
}
/// A container that gradually changes its values over a period of time. /// A container that gradually changes its values over a period of time.
/// ///
/// The [AnimatedContainer] will automatically animate between the old and /// The [AnimatedContainer] will automatically animate between the old and
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment