Skip to content

Commit 4a32e52

Browse files
authored
SpringDescription parameter for the AnimationController fling method (flutter#65057)
1 parent 3302a12 commit 4a32e52

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,4 @@ meritozh <ah841814092@gmail.com>
6868
Terrence Addison Tandijono(flotilla) <terrenceaddison32@gmail.com>
6969
YeungKC <flutter@yeungkc.com>
7070
Nobuhiro Tabuki <japanese.around30@gmail.com>
71+
nt4f04uNd <nt4f04und@gmail.com>

packages/flutter/lib/src/animation/animation_controller.dart

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -645,18 +645,27 @@ class AnimationController extends Animation<double>
645645
_checkStatusChanged();
646646
}
647647

648-
/// Drives the animation with a critically damped spring (within [lowerBound]
649-
/// and [upperBound]) and initial velocity.
648+
/// Drives the animation with a spring (within [lowerBound] and [upperBound])
649+
/// and initial velocity.
650650
///
651651
/// If velocity is positive, the animation will complete, otherwise it will
652652
/// dismiss.
653653
///
654+
/// The [springDescription] parameter can be used to specify a custom [SpringType.criticallyDamped]
655+
/// or [SpringType.overDamped] spring to drive the animation with. Defaults to null, which uses a
656+
/// [SpringType.criticallyDamped] spring. See [SpringDescription.withDampingRatio] for how
657+
/// to create a suitable [SpringDescription].
658+
///
659+
/// The resulting spring simulation cannot be of type [SpringType.underDamped],
660+
/// as this can lead to unexpected look of the produced animation.
661+
///
654662
/// Returns a [TickerFuture] that completes when the animation is complete.
655663
///
656664
/// The most recently returned [TickerFuture], if any, is marked as having been
657665
/// canceled, meaning the future never completes and its [TickerFuture.orCancel]
658666
/// derivative future completes with a [TickerCanceled] error.
659-
TickerFuture fling({ double velocity = 1.0, AnimationBehavior? animationBehavior }) {
667+
TickerFuture fling({ double velocity = 1.0, SpringDescription? springDescription, AnimationBehavior? animationBehavior }) {
668+
springDescription ??= _kFlingSpringDescription;
660669
_direction = velocity < 0.0 ? _AnimationDirection.reverse : _AnimationDirection.forward;
661670
final double target = velocity < 0.0 ? lowerBound - _kFlingTolerance.distance
662671
: upperBound + _kFlingTolerance.distance;
@@ -673,8 +682,13 @@ class AnimationController extends Animation<double>
673682
break;
674683
}
675684
}
676-
final Simulation simulation = SpringSimulation(_kFlingSpringDescription, value, target, velocity * scale)
685+
final SpringSimulation simulation = SpringSimulation(springDescription, value, target, velocity * scale)
677686
..tolerance = _kFlingTolerance;
687+
assert(
688+
simulation.type != SpringType.underDamped,
689+
'The resulting spring simulation is of type SpringType.underDamped.\n'
690+
'This can lead to unexpected look of the animation, please adjust the springDescription parameter'
691+
);
678692
stop();
679693
return _startSimulation(simulation);
680694
}

packages/flutter/test/animation/animation_controller_test.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,29 @@ void main() {
253253
largeRangeController.stop();
254254
});
255255

256+
test('Custom springDescription can be applied', () {
257+
final AnimationController controller = AnimationController(
258+
vsync: const TestVSync(),
259+
);
260+
final AnimationController customSpringController = AnimationController(
261+
vsync: const TestVSync(),
262+
);
263+
264+
controller.fling();
265+
// Will produce longer and smoother animation than the default.
266+
customSpringController.fling(
267+
springDescription: SpringDescription.withDampingRatio(
268+
mass: 0.01,
269+
stiffness: 10.0,
270+
ratio: 2.0,
271+
),
272+
);
273+
tick(const Duration(milliseconds: 0));
274+
tick(const Duration(milliseconds: 50));
275+
276+
expect(customSpringController.value < controller.value, true);
277+
});
278+
256279
test('lastElapsedDuration control test', () {
257280
final AnimationController controller = AnimationController(
258281
duration: const Duration(milliseconds: 100),

0 commit comments

Comments
 (0)