Commit 6722e3d5 authored by Adam Barth's avatar Adam Barth

Animation status callbacks should be re-entrant

We should mutate the status of the AnimationController before calling
the status callbacks so that we're prepared to be re-entered.

Fixes #1911
parent 9e56fc4e
...@@ -163,10 +163,11 @@ class AnimationController extends Animation<double> ...@@ -163,10 +163,11 @@ class AnimationController extends Animation<double>
AnimationStatus _lastStatus = AnimationStatus.dismissed; AnimationStatus _lastStatus = AnimationStatus.dismissed;
void _checkStatusChanged() { void _checkStatusChanged() {
AnimationStatus currentStatus = status; AnimationStatus newStatus = status;
if (currentStatus != _lastStatus) AnimationStatus oldStatus = _lastStatus;
notifyStatusListeners(status); _lastStatus = newStatus;
_lastStatus = currentStatus; if (oldStatus != newStatus)
notifyStatusListeners(newStatus);
} }
/// Drives the animation from its current value to target. /// Drives the animation from its current value to target.
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/animation.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
void main() {
test("Can set value during status callback", () {
WidgetFlutterBinding.ensureInitialized();
AnimationController controller = new AnimationController(
duration: const Duration(milliseconds: 100)
);
bool didComplete = false;
bool didDismiss = false;
controller.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed) {
didComplete = true;
controller.value = 0.0;
controller.forward();
} else if (status == AnimationStatus.dismissed) {
didDismiss = true;
controller.value = 0.0;
controller.forward();
}
});
controller.forward();
expect(didComplete, isFalse);
expect(didDismiss, isFalse);
Scheduler.instance.handleBeginFrame(const Duration(seconds: 1));
expect(didComplete, isFalse);
expect(didDismiss, isFalse);
Scheduler.instance.handleBeginFrame(const Duration(seconds: 2));
expect(didComplete, isTrue);
expect(didDismiss, isTrue);
});
}
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