Commit 25ab5555 authored by Adam Barth's avatar Adam Barth

Elide fewer AnimationStatus callbacks

Previously we would elide forward and reverse callbacks that canceled each
other out, which broke the expected state machine. Now we synchronously deliver
status callbacks when start an animation.

Fixes #1913
parent 19b9464e
......@@ -146,6 +146,7 @@ class AnimationController extends Animation<double>
stop();
if (simulationDuration == Duration.ZERO) {
assert(value == target);
_checkStatusChanged();
return new Future.value();
}
assert(simulationDuration > Duration.ZERO);
......@@ -180,7 +181,9 @@ class AnimationController extends Animation<double>
assert(!isAnimating);
_simulation = simulation;
_value = simulation.x(0.0).clamp(lowerBound, upperBound);
return _ticker.start();
Future result = _ticker.start();
_checkStatusChanged();
return result;
}
/// Stops running this animation.
......@@ -194,13 +197,13 @@ class AnimationController extends Animation<double>
stop();
}
AnimationStatus _lastStatus = AnimationStatus.dismissed;
AnimationStatus _lastReportedStatus = AnimationStatus.dismissed;
void _checkStatusChanged() {
AnimationStatus newStatus = status;
AnimationStatus oldStatus = _lastStatus;
_lastStatus = newStatus;
if (oldStatus != newStatus)
if (_lastReportedStatus != newStatus) {
_lastReportedStatus = newStatus;
notifyStatusListeners(newStatus);
}
}
void _tick(Duration elapsed) {
......
......@@ -22,9 +22,9 @@ class OverlayEntry {
bool get opaque => _opaque;
bool _opaque;
void set opaque (bool value) {
assert(_overlay != null);
if (_opaque == value)
return;
assert(_overlay != null);
_overlay.setState(() {
_opaque = value;
});
......
......@@ -36,5 +36,70 @@ void main() {
Scheduler.instance.handleBeginFrame(const Duration(seconds: 2));
expect(didComplete, isTrue);
expect(didDismiss, isTrue);
controller.stop();
});
test("Receives status callbacks for forward and reverse", () {
WidgetFlutterBinding.ensureInitialized();
AnimationController controller = new AnimationController(
duration: const Duration(milliseconds: 100)
);
List<double> valueLog = <double>[];
List<AnimationStatus> log = <AnimationStatus>[];
controller
..addStatusListener((AnimationStatus status) {
log.add(status);
})
..addListener(() {
valueLog.add(controller.value);
});
expect(log, equals([]));
expect(valueLog, equals([]));
controller.forward();
expect(log, equals([AnimationStatus.forward]));
expect(valueLog, equals([]));
controller.reverse();
expect(log, equals([AnimationStatus.forward, AnimationStatus.dismissed]));
expect(valueLog, equals([]));
controller.reverse();
expect(log, equals([AnimationStatus.forward, AnimationStatus.dismissed]));
expect(valueLog, equals([]));
log.clear();
controller.forward();
expect(log, equals([AnimationStatus.forward]));
expect(valueLog, equals([]));
controller.forward();
expect(log, equals([AnimationStatus.forward]));
expect(valueLog, equals([]));
controller.reverse();
log.clear();
Scheduler.instance.handleBeginFrame(const Duration(seconds: 10));
expect(log, equals([]));
expect(valueLog, equals([]));
Scheduler.instance.handleBeginFrame(const Duration(seconds: 20));
expect(log, equals([]));
expect(valueLog, equals([]));
Scheduler.instance.handleBeginFrame(const Duration(seconds: 30));
expect(log, equals([]));
expect(valueLog, equals([]));
Scheduler.instance.handleBeginFrame(const Duration(seconds: 40));
expect(log, equals([]));
expect(valueLog, equals([]));
controller.stop();
});
}
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