@@ -118,6 +118,7 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
118
118
Duration ? delay,
119
119
this .controller,
120
120
this .adapter,
121
+ this .value,
121
122
this .target,
122
123
}) : autoPlay = autoPlay ?? true ,
123
124
delay = delay ?? Duration .zero {
@@ -134,6 +135,7 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
134
135
warn (autoPlay != false , '$s Animate.autoPlay=false' );
135
136
warn (adapter == null , '$s Animate.adapter' );
136
137
warn (target == null , '$s Animate.target' );
138
+ warn (value == null , '$s Animate.value' );
137
139
}
138
140
_entries = [];
139
141
if (effects != null ) addEffects (effects);
@@ -193,7 +195,8 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
193
195
final Duration delay;
194
196
195
197
/// An external [AnimationController] can optionally be specified. By default
196
- /// Animate creates its own controller internally.
198
+ /// Animate creates its own controller internally, which can be accessed via
199
+ /// [onInit] or [onPlay] .
197
200
final AnimationController ? controller;
198
201
199
202
/// An [Adapter] can drive the animation from an external source (ex. a [ScrollController] ,
@@ -216,6 +219,18 @@ class Animate extends StatefulWidget with AnimateManager<Animate> {
216
219
/// ```
217
220
final double ? target;
218
221
222
+ /// Sets an initial position for the animation between 0 (start) and 1 (end).
223
+ /// This corresponds to the `value` of the animation's [controller] .
224
+ /// When [value] is changed, it will jump to the new position.
225
+ ///
226
+ /// For example, this can be used with [autoPlay] `=false` to display an animation
227
+ /// at a specific point (half way through a fade in this case):
228
+ ///
229
+ /// ```
230
+ /// foo.animate(value: 0.5, autoPlay: false).fadeIn()
231
+ /// ```
232
+ final double ? value;
233
+
219
234
late final List <EffectEntry > _entries;
220
235
Duration _duration = Duration .zero;
221
236
EffectEntry ? _lastEntry;
@@ -279,9 +294,8 @@ class _AnimateState extends State<Animate> with SingleTickerProviderStateMixin {
279
294
_play ();
280
295
} else if (oldWidget.adapter != widget.adapter) {
281
296
_initAdapter ();
282
- } else if (widget.target != oldWidget.target) {
283
- // we don't restart when onPlay changes, because anonymous functions
284
- // can only be compared as strings, which is expensive.
297
+ } else if (widget.target != oldWidget.target ||
298
+ widget.value != oldWidget.value) {
285
299
_play ();
286
300
}
287
301
super .didUpdateWidget (oldWidget);
@@ -296,6 +310,7 @@ class _AnimateState extends State<Animate> with SingleTickerProviderStateMixin {
296
310
void _restart () {
297
311
_delayed? .ignore ();
298
312
_initController ();
313
+ _updateValue ();
299
314
_delayed = Future .delayed (widget.delay, () => _play ());
300
315
}
301
316
@@ -305,8 +320,8 @@ class _AnimateState extends State<Animate> with SingleTickerProviderStateMixin {
305
320
306
321
if (widget.controller != null ) {
307
322
// externally provided AnimationController.
323
+ _disposeController ();
308
324
controller = widget.controller! ;
309
- _isInternalController = false ;
310
325
} else if (! _isInternalController) {
311
326
// create a new internal AnimationController.
312
327
controller = AnimationController (vsync: this );
@@ -355,15 +370,21 @@ class _AnimateState extends State<Animate> with SingleTickerProviderStateMixin {
355
370
356
371
void _play () {
357
372
_delayed? .ignore (); // for poorly timed hot reloads.
373
+ _updateValue ();
358
374
double ? pos = widget.target;
359
375
if (pos != null ) {
360
376
_controller.animateTo (pos);
361
377
} else if (widget.autoPlay && _adapter == null ) {
362
- _controller.forward (from: 0 );
378
+ _controller.forward (from: widget.value ?? 0 );
363
379
widget.onPlay? .call (_controller);
364
380
}
365
381
}
366
382
383
+ void _updateValue () {
384
+ if (widget.value == null ) return ;
385
+ _controller.value = widget.value! ;
386
+ }
387
+
367
388
@override
368
389
Widget build (BuildContext context) {
369
390
Widget child = widget.child, parent = child;
@@ -390,6 +411,7 @@ extension AnimateWidgetExtensions on Widget {
390
411
AnimationController ? controller,
391
412
Adapter ? adapter,
392
413
double ? target,
414
+ double ? value,
393
415
}) =>
394
416
Animate (
395
417
key: key,
@@ -402,6 +424,7 @@ extension AnimateWidgetExtensions on Widget {
402
424
controller: controller,
403
425
adapter: adapter,
404
426
target: target,
427
+ value: value,
405
428
child: this ,
406
429
);
407
430
}
0 commit comments