Unverified Commit 31318b0e authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Add documentation to ImplicitlyAnimatedWidgetState (#33674)

This is a follow-on to #33370 based on review comments
therein.
parent 264381a6
...@@ -212,13 +212,17 @@ class TextStyleTween extends Tween<TextStyle> { ...@@ -212,13 +212,17 @@ class TextStyleTween extends Tween<TextStyle> {
TextStyle lerp(double t) => TextStyle.lerp(begin, end, t); TextStyle lerp(double t) => TextStyle.lerp(begin, end, t);
} }
/// An abstract widget for building widgets that gradually change their /// An abstract class for building widgets that animate changes to their
/// values over a period of time. /// properties.
/// ///
/// Subclasses' States must provide a way to visit the subclass's relevant /// Widgets of this type will not animate when they are first added to the
/// fields to animate. [ImplicitlyAnimatedWidget] will then automatically /// widget tree. Rather, when they are rebuilt with different values, they will
/// interpolate and animate those fields using the provided duration and /// respond to those _changes_ by animating the changes over a specified
/// curve when those fields change. /// [duration].
///
/// Which properties are animated is left up to the subclass. Subclasses' States
/// must extend [ImplicitlyAnimatedWidgetState] and provide a way to visit the
/// relevant fields to animate.
abstract class ImplicitlyAnimatedWidget extends StatefulWidget { abstract class ImplicitlyAnimatedWidget extends StatefulWidget {
/// Initializes fields for subclasses. /// Initializes fields for subclasses.
/// ///
...@@ -259,20 +263,44 @@ abstract class ImplicitlyAnimatedWidget extends StatefulWidget { ...@@ -259,20 +263,44 @@ abstract class ImplicitlyAnimatedWidget extends StatefulWidget {
/// ///
/// This is the type of one of the arguments of [TweenVisitor], the signature /// This is the type of one of the arguments of [TweenVisitor], the signature
/// used by [AnimatedWidgetBaseState.forEachTween]. /// used by [AnimatedWidgetBaseState.forEachTween].
///
/// Instances of this function are expected to take a value and return a tween
/// beginning at that value.
typedef TweenConstructor<T> = Tween<T> Function(T targetValue); typedef TweenConstructor<T> = Tween<T> Function(T targetValue);
/// Signature for callbacks passed to [AnimatedWidgetBaseState.forEachTween]. /// Signature for callbacks passed to [ImplicitlyAnimatedWidgetState.forEachTween].
///
/// {@template flutter.widgets.implicit_animations.tweenVisitorArguments}
/// The `tween` argument should contain the current tween value. This will
/// initially be null when the state is first initialized.
///
/// The `targetValue` argument should contain the value toward which the state
/// is animating. For instance, if the state is animating its widget's
/// opacity value, then this argument should contain the widget's current
/// opacity value.
///
/// The `constructor` argument should contain a function that takes a value
/// (the widget's value being animated) and returns a tween beginning at that
/// value.
///
/// {@endtemplate}
///
/// `forEachTween()` is expected to update its tween value to the return value
/// of this visitor.
///
/// The `<T>` parameter specifies the type of value that's being animated.
typedef TweenVisitor<T> = Tween<T> Function(Tween<T> tween, T targetValue, TweenConstructor<T> constructor); typedef TweenVisitor<T> = Tween<T> Function(Tween<T> tween, T targetValue, TweenConstructor<T> constructor);
/// A base class for widgets with implicit animations. /// A base class for the `State` of widgets with implicit animations.
/// ///
/// [ImplicitlyAnimatedWidgetState] requires that subclasses respond to the /// [ImplicitlyAnimatedWidgetState] requires that subclasses respond to the
/// animation, themselves. If you would like `setState()` to be called /// animation themselves. If you would like `setState()` to be called
/// automatically as the animation changes, use [AnimatedWidgetBaseState]. /// automatically as the animation changes, use [AnimatedWidgetBaseState].
/// ///
/// Subclasses must implement the [forEachTween] method to allow /// Properties that subclasses choose to animate are represented by [Tween]
/// [ImplicitlyAnimatedWidgetState] to iterate through the subclasses' widget's /// instances. Subclasses must implement the [forEachTween] method to allow
/// fields and animate them. /// [ImplicitlyAnimatedWidgetState] to iterate through the widget's fields and
/// animate them.
abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> extends State<T> with SingleTickerProviderStateMixin<T> { abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> extends State<T> with SingleTickerProviderStateMixin<T> {
/// The animation controller driving this widget's implicit animations. /// The animation controller driving this widget's implicit animations.
@protected @protected
...@@ -356,21 +384,36 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> ...@@ -356,21 +384,36 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
return shouldStartAnimation; return shouldStartAnimation;
} }
/// Subclasses must implement this function by running through the following /// Visits each tween controlled by this state with the specified `visitor`
/// steps for each animatable facet in the class: /// function.
/// ///
/// 1. Call the visitor callback with three arguments, the first argument /// ### Subclass responsibility
/// being the current value of the Tween<T> object that represents the
/// tween (initially null), the second argument, of type T, being the value
/// on the Widget that represents the current target value of the
/// tween, and the third being a callback that takes a value T (which will
/// be the second argument to the visitor callback), and that returns an
/// Tween<T> object for the tween, configured with the given value
/// as the begin value.
/// ///
/// 2. Take the value returned from the callback, and store it. This is the /// Properties to be animated are represented by [Tween] member variables in
/// value to use as the current value the next time that the [forEachTween] /// the state. For each such tween, [forEachTween] implementations are
/// method is called. /// expected to call `visitor` with the appropriate arguments and store the
/// result back into the member variable. The arguments to `visitor` are as
/// follows:
///
/// {@macro flutter.widgets.implicit_animations.tweenVisitorArguments}
///
/// ### When this method will be called
///
/// [forEachTween] is initially called during [initState]. It is expected that
/// the visitor's `tween` argument will be set to null, causing the visitor to
/// call its `constructor` argument to construct the tween for the first time.
/// The resulting tween will have its `begin` value set to the target value
/// and will have its `end` value set to null. The animation will not be
/// started.
///
/// When this state's [widget] is updated (thus triggering the
/// [didUpdateWidget] method to be called), [forEachTween] will be called
/// again to check if the target value has changed. If the target value has
/// changed, signaling that the [animation] should start, then the visitor
/// will update the tween's `start` and `end` values accordingly, and the
/// animation will be started.
///
/// ### Other member variables
/// ///
/// Subclasses that contain properties based on tweens created by /// Subclasses that contain properties based on tweens created by
/// [forEachTween] should override [didUpdateTweens] to update those /// [forEachTween] should override [didUpdateTweens] to update those
...@@ -379,7 +422,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> ...@@ -379,7 +422,7 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
/// ///
/// {@tool sample} /// {@tool sample}
/// ///
/// Sample code implementing an implicitly animated widget's `State`. /// This sample implements an implicitly animated widget's `State`.
/// The widget animates between colors whenever `widget.targetColor` /// The widget animates between colors whenever `widget.targetColor`
/// changes. /// changes.
/// ///
...@@ -423,6 +466,20 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> ...@@ -423,6 +466,20 @@ abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget>
/// ///
/// Any properties that depend upon tweens created by [forEachTween] should be /// Any properties that depend upon tweens created by [forEachTween] should be
/// updated within [didUpdateTweens], not within [forEachTween]. /// updated within [didUpdateTweens], not within [forEachTween].
///
/// This method will be called both:
///
/// 1. After the tweens are _initially_ constructed (by
/// the `constructor` argument to the [TweenVisitor] that's passed to
/// [forEachTween]). In this case, the tweens are likely to contain only
/// a [Tween.begin] value and not a [Tween.end].
///
/// 2. When the state's [widget] is updated, and one or more of the tweens
/// visited by [forEachTween] specifies a target value that's different
/// than the widget's current value, thus signaling that the [animation]
/// should run. In this case, the [Tween.begin] value for each tween will
/// an evaluation of the tween against the current [animation], and the
/// [Tween.end] value for each tween will be the target value.
@protected @protected
void didUpdateTweens() { } void didUpdateTweens() { }
} }
......
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