Unverified Commit a7e868dd authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate animation to nullsafety (#62485)

* migrate animation to nullsafety

* nullable tween

* fix generic type issue

* address review comment
parent d6a25ae6
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// The Flutter animation system.
///
/// To use, import `package:flutter/animation.dart`.
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'dart:ui' as ui show lerpDouble;
......@@ -233,14 +232,14 @@ class AnimationController extends Animation<double>
/// changed by calling [resync]. It is required and must not be null. See
/// [TickerProvider] for advice on obtaining a ticker provider.
AnimationController({
double value,
double? value,
this.duration,
this.reverseDuration,
this.debugLabel,
this.lowerBound = 0.0,
this.upperBound = 1.0,
this.animationBehavior = AnimationBehavior.normal,
@required TickerProvider vsync,
required TickerProvider vsync,
}) : assert(lowerBound != null),
assert(upperBound != null),
assert(upperBound >= lowerBound),
......@@ -272,7 +271,7 @@ class AnimationController extends Animation<double>
this.duration,
this.reverseDuration,
this.debugLabel,
@required TickerProvider vsync,
required TickerProvider vsync,
this.animationBehavior = AnimationBehavior.preserve,
}) : assert(value != null),
assert(vsync != null),
......@@ -291,7 +290,7 @@ class AnimationController extends Animation<double>
/// A label that is used in the [toString] output. Intended to aid with
/// identifying animation controller instances in debug output.
final String debugLabel;
final String? debugLabel;
/// The behavior of the controller when [AccessibilityFeatures.disableAnimations]
/// is true.
......@@ -310,24 +309,24 @@ class AnimationController extends Animation<double>
///
/// If [reverseDuration] is specified, then [duration] is only used when going
/// [forward]. Otherwise, it specifies the duration going in both directions.
Duration duration;
Duration? duration;
/// The length of time this animation should last when going in [reverse].
///
/// The value of [duration] us used if [reverseDuration] is not specified or
/// set to null.
Duration reverseDuration;
Duration? reverseDuration;
Ticker _ticker;
Ticker? _ticker;
/// Recreates the [Ticker] with the new [TickerProvider].
void resync(TickerProvider vsync) {
final Ticker oldTicker = _ticker;
final Ticker oldTicker = _ticker!;
_ticker = vsync.createTicker(_tick);
_ticker.absorbTicker(oldTicker);
_ticker!.absorbTicker(oldTicker);
}
Simulation _simulation;
Simulation? _simulation;
/// The current value of the animation.
///
......@@ -339,7 +338,7 @@ class AnimationController extends Animation<double>
/// listeners.
@override
double get value => _value;
double _value;
late double _value;
/// Stops the animation controller and sets the current value of the
/// animation.
///
......@@ -394,7 +393,7 @@ class AnimationController extends Animation<double>
double get velocity {
if (!isAnimating)
return 0.0;
return _simulation.dx(lastElapsedDuration.inMicroseconds.toDouble() / Duration.microsecondsPerSecond);
return _simulation!.dx(lastElapsedDuration!.inMicroseconds.toDouble() / Duration.microsecondsPerSecond);
}
void _internalSetValue(double newValue) {
......@@ -414,8 +413,8 @@ class AnimationController extends Animation<double>
/// and the most recent tick of the animation.
///
/// If the controller is not animating, the last elapsed duration is null.
Duration get lastElapsedDuration => _lastElapsedDuration;
Duration _lastElapsedDuration;
Duration? get lastElapsedDuration => _lastElapsedDuration;
Duration? _lastElapsedDuration;
/// Whether this animation is currently animating in either the forward or reverse direction.
///
......@@ -423,13 +422,13 @@ class AnimationController extends Animation<double>
/// controller's ticker might get muted, in which case the animation
/// controller's callbacks will no longer fire even though time is continuing
/// to pass. See [Ticker.muted] and [TickerMode].
bool get isAnimating => _ticker != null && _ticker.isActive;
bool get isAnimating => _ticker != null && _ticker!.isActive;
_AnimationDirection _direction;
@override
AnimationStatus get status => _status;
AnimationStatus _status;
late AnimationStatus _status;
/// Starts running this animation forwards (towards the end).
///
......@@ -442,7 +441,7 @@ class AnimationController extends Animation<double>
/// During the animation, [status] is reported as [AnimationStatus.forward],
/// which switches to [AnimationStatus.completed] when [upperBound] is
/// reached at the end of the animation.
TickerFuture forward({ double from }) {
TickerFuture forward({ double? from }) {
assert(() {
if (duration == null) {
throw FlutterError(
......@@ -475,7 +474,7 @@ class AnimationController extends Animation<double>
/// During the animation, [status] is reported as [AnimationStatus.reverse],
/// which switches to [AnimationStatus.dismissed] when [lowerBound] is
/// reached at the end of the animation.
TickerFuture reverse({ double from }) {
TickerFuture reverse({ double? from }) {
assert(() {
if (duration == null && reverseDuration == null) {
throw FlutterError(
......@@ -509,7 +508,7 @@ class AnimationController extends Animation<double>
/// regardless of whether `target` > [value] or not. At the end of the
/// animation, when `target` is reached, [status] is reported as
/// [AnimationStatus.completed].
TickerFuture animateTo(double target, { Duration duration, Curve curve = Curves.linear }) {
TickerFuture animateTo(double target, { Duration? duration, Curve curve = Curves.linear }) {
assert(
_ticker != null,
'AnimationController.animateTo() called after AnimationController.dispose()\n'
......@@ -531,7 +530,7 @@ class AnimationController extends Animation<double>
/// regardless of whether `target` < [value] or not. At the end of the
/// animation, when `target` is reached, [status] is reported as
/// [AnimationStatus.dismissed].
TickerFuture animateBack(double target, { Duration duration, Curve curve = Curves.linear }) {
TickerFuture animateBack(double target, { Duration? duration, Curve curve = Curves.linear }) {
assert(
_ticker != null,
'AnimationController.animateBack() called after AnimationController.dispose()\n'
......@@ -541,9 +540,9 @@ class AnimationController extends Animation<double>
return _animateToInternal(target, duration: duration, curve: curve);
}
TickerFuture _animateToInternal(double target, { Duration duration, Curve curve = Curves.linear }) {
TickerFuture _animateToInternal(double target, { Duration? duration, Curve curve = Curves.linear }) {
double scale = 1.0;
if (SemanticsBinding.instance.disableAnimations) {
if (SemanticsBinding.instance!.disableAnimations) {
switch (animationBehavior) {
case AnimationBehavior.normal:
// Since the framework cannot handle zero duration animations, we run it at 5% of the normal
......@@ -555,7 +554,7 @@ class AnimationController extends Animation<double>
break;
}
}
Duration simulationDuration = duration;
Duration? simulationDuration = duration;
if (simulationDuration == null) {
assert(() {
if ((this.duration == null && _direction == _AnimationDirection.reverse && reverseDuration == null) || this.duration == null) {
......@@ -572,8 +571,8 @@ class AnimationController extends Animation<double>
final double remainingFraction = range.isFinite ? (target - _value).abs() / range : 1.0;
final Duration directionDuration =
(_direction == _AnimationDirection.reverse && reverseDuration != null)
? reverseDuration
: this.duration;
? reverseDuration!
: this.duration!;
simulationDuration = directionDuration * remainingFraction;
} else if (target == value) {
// Already at target, don't animate.
......@@ -617,7 +616,7 @@ class AnimationController extends Animation<double>
/// The most recently returned [TickerFuture], if any, is marked as having been
/// canceled, meaning the future never completes and its [TickerFuture.orCancel]
/// derivative future completes with a [TickerCanceled] error.
TickerFuture repeat({ double min, double max, bool reverse = false, Duration period }) {
TickerFuture repeat({ double? min, double? max, bool reverse = false, Duration? period }) {
min ??= lowerBound;
max ??= upperBound;
period ??= duration;
......@@ -636,7 +635,7 @@ class AnimationController extends Animation<double>
assert(max <= upperBound && min >= lowerBound);
assert(reverse != null);
stop();
return _startSimulation(_RepeatingSimulation(_value, min, max, reverse, period, _directionSetter));
return _startSimulation(_RepeatingSimulation(_value, min, max, reverse, period!, _directionSetter));
}
void _directionSetter(_AnimationDirection direction) {
......@@ -658,13 +657,13 @@ class AnimationController extends Animation<double>
/// The most recently returned [TickerFuture], if any, is marked as having been
/// canceled, meaning the future never completes and its [TickerFuture.orCancel]
/// derivative future completes with a [TickerCanceled] error.
TickerFuture fling({ double velocity = 1.0, AnimationBehavior animationBehavior }) {
TickerFuture fling({ double velocity = 1.0, AnimationBehavior? animationBehavior }) {
_direction = velocity < 0.0 ? _AnimationDirection.reverse : _AnimationDirection.forward;
final double target = velocity < 0.0 ? lowerBound - _kFlingTolerance.distance
: upperBound + _kFlingTolerance.distance;
double scale = 1.0;
final AnimationBehavior behavior = animationBehavior ?? this.animationBehavior;
if (SemanticsBinding.instance.disableAnimations) {
if (SemanticsBinding.instance!.disableAnimations) {
switch (behavior) {
case AnimationBehavior.normal:
// TODO(jonahwilliams): determine a better process for setting velocity.
......@@ -712,7 +711,7 @@ class AnimationController extends Animation<double>
_simulation = simulation;
_lastElapsedDuration = Duration.zero;
_value = simulation.x(0.0).clamp(lowerBound, upperBound) as double;
final TickerFuture result = _ticker.start();
final TickerFuture result = _ticker!.start();
_status = (_direction == _AnimationDirection.forward) ?
AnimationStatus.forward :
AnimationStatus.reverse;
......@@ -745,7 +744,7 @@ class AnimationController extends Animation<double>
);
_simulation = null;
_lastElapsedDuration = null;
_ticker.stop(canceled: canceled);
_ticker!.stop(canceled: canceled);
}
/// Release the resources used by this object. The object is no longer usable
......@@ -770,7 +769,7 @@ class AnimationController extends Animation<double>
}
return true;
}());
_ticker.dispose();
_ticker!.dispose();
_ticker = null;
super.dispose();
}
......@@ -788,8 +787,8 @@ class AnimationController extends Animation<double>
_lastElapsedDuration = elapsed;
final double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.microsecondsPerSecond;
assert(elapsedInSeconds >= 0.0);
_value = _simulation.x(elapsedInSeconds).clamp(lowerBound, upperBound) as double;
if (_simulation.isDone(elapsedInSeconds)) {
_value = _simulation!.x(elapsedInSeconds).clamp(lowerBound, upperBound) as double;
if (_simulation!.isDone(elapsedInSeconds)) {
_status = (_direction == _AnimationDirection.forward) ?
AnimationStatus.completed :
AnimationStatus.dismissed;
......@@ -802,7 +801,7 @@ class AnimationController extends Animation<double>
@override
String toStringDetails() {
final String paused = isAnimating ? '' : '; paused';
final String ticker = _ticker == null ? '; DISPOSED' : (_ticker.muted ? '; silenced' : '');
final String ticker = _ticker == null ? '; DISPOSED' : (_ticker!.muted ? '; silenced' : '');
final String label = debugLabel == null ? '' : '; for $debugLabel';
final String more = '${super.toStringDetails()} ${value.toStringAsFixed(3)}';
return '$more$paused$ticker$label';
......@@ -870,10 +869,10 @@ class _RepeatingSimulation extends Simulation {
if (reverse && _isPlayingReverse) {
directionSetter(_AnimationDirection.reverse);
return ui.lerpDouble(max, min, t);
return ui.lerpDouble(max, min, t)!;
} else {
directionSetter(_AnimationDirection.forward);
return ui.lerpDouble(min, max, t);
return ui.lerpDouble(min, max, t)!;
}
}
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
......@@ -171,7 +170,7 @@ class ProxyAnimation extends Animation<double>
///
/// If the animation argument is omitted, the proxy animation will have the
/// status [AnimationStatus.dismissed] and a value of 0.0.
ProxyAnimation([Animation<double> animation]) {
ProxyAnimation([Animation<double>? animation]) {
_parent = animation;
if (_parent == null) {
_status = AnimationStatus.dismissed;
......@@ -179,21 +178,21 @@ class ProxyAnimation extends Animation<double>
}
}
AnimationStatus _status;
double _value;
AnimationStatus? _status;
double? _value;
/// The animation whose value this animation will proxy.
///
/// This value is mutable. When mutated, the listeners on the proxy animation
/// will be transparently updated to be listening to the new parent animation.
Animation<double> get parent => _parent;
Animation<double> _parent;
set parent(Animation<double> value) {
Animation<double>? get parent => _parent;
Animation<double>? _parent;
set parent(Animation<double>? value) {
if (value == _parent)
return;
if (_parent != null) {
_status = _parent.status;
_value = _parent.value;
_status = _parent!.status;
_value = _parent!.value;
if (isListening)
didStopListening();
}
......@@ -201,10 +200,10 @@ class ProxyAnimation extends Animation<double>
if (_parent != null) {
if (isListening)
didStartListening();
if (_value != _parent.value)
if (_value != _parent!.value)
notifyListeners();
if (_status != _parent.status)
notifyStatusListeners(_parent.status);
if (_status != _parent!.status)
notifyStatusListeners(_parent!.status);
_status = null;
_value = null;
}
......@@ -213,24 +212,24 @@ class ProxyAnimation extends Animation<double>
@override
void didStartListening() {
if (_parent != null) {
_parent.addListener(notifyListeners);
_parent.addStatusListener(notifyStatusListeners);
_parent!.addListener(notifyListeners);
_parent!.addStatusListener(notifyStatusListeners);
}
}
@override
void didStopListening() {
if (_parent != null) {
_parent.removeListener(notifyListeners);
_parent.removeStatusListener(notifyStatusListeners);
_parent!.removeListener(notifyListeners);
_parent!.removeStatusListener(notifyStatusListeners);
}
}
@override
AnimationStatus get status => _parent != null ? _parent.status : _status;
AnimationStatus get status => _parent != null ? _parent!.status : _status!;
@override
double get value => _parent != null ? _parent.value : _value;
double get value => _parent != null ? _parent!.value : _value!;
@override
String toString() {
......@@ -307,7 +306,6 @@ class ReverseAnimation extends Animation<double>
case AnimationStatus.completed: return AnimationStatus.dismissed;
case AnimationStatus.dismissed: return AnimationStatus.completed;
}
return null;
}
@override
......@@ -372,8 +370,8 @@ class CurvedAnimation extends Animation<double> with AnimationWithParentMixin<do
///
/// The parent and curve arguments must not be null.
CurvedAnimation({
@required this.parent,
@required this.curve,
required this.parent,
required this.curve,
this.reverseCurve,
}) : assert(parent != null),
assert(curve != null) {
......@@ -401,14 +399,14 @@ class CurvedAnimation extends Animation<double> with AnimationWithParentMixin<do
/// discontinuities.
///
/// If this field is null, uses [curve] in both directions.
Curve reverseCurve;
Curve? reverseCurve;
/// The direction used to select the current curve.
///
/// The curve direction is only reset when we hit the beginning or the end of
/// the timeline to avoid discontinuities in the value of any variables this
/// animation is used to animate.
AnimationStatus _curveDirection;
AnimationStatus? _curveDirection;
void _updateCurveDirection(AnimationStatus status) {
switch (status) {
......@@ -431,7 +429,7 @@ class CurvedAnimation extends Animation<double> with AnimationWithParentMixin<do
@override
double get value {
final Curve activeCurve = _useForwardCurve ? curve : reverseCurve;
final Curve? activeCurve = _useForwardCurve ? curve : reverseCurve;
final double t = parent.value;
if (activeCurve == null)
......@@ -496,18 +494,18 @@ class TrainHoppingAnimation extends Animation<double>
TrainHoppingAnimation(this._currentTrain, this._nextTrain, { this.onSwitchedTrain })
: assert(_currentTrain != null) {
if (_nextTrain != null) {
if (_currentTrain.value == _nextTrain.value) {
_currentTrain = _nextTrain;
if (_currentTrain!.value == _nextTrain!.value) {
_currentTrain = _nextTrain!;
_nextTrain = null;
} else if (_currentTrain.value > _nextTrain.value) {
} else if (_currentTrain!.value > _nextTrain!.value) {
_mode = _TrainHoppingMode.maximize;
} else {
assert(_currentTrain.value < _nextTrain.value);
assert(_currentTrain!.value < _nextTrain!.value);
_mode = _TrainHoppingMode.minimize;
}
}
_currentTrain.addStatusListener(_statusChangeHandler);
_currentTrain.addListener(_valueChangeHandler);
_currentTrain!.addStatusListener(_statusChangeHandler);
_currentTrain!.addListener(_valueChangeHandler);
_nextTrain?.addListener(_valueChangeHandler);
assert(_mode != null || _nextTrain == null);
}
......@@ -516,19 +514,19 @@ class TrainHoppingAnimation extends Animation<double>
///
/// The identity of this object will change from the first animation to the
/// second animation when [onSwitchedTrain] is called.
Animation<double> get currentTrain => _currentTrain;
Animation<double> _currentTrain;
Animation<double> _nextTrain;
_TrainHoppingMode _mode;
Animation<double>? get currentTrain => _currentTrain;
Animation<double>? _currentTrain;
Animation<double>? _nextTrain;
_TrainHoppingMode? _mode;
/// Called when this animation switches to be driven by the second animation.
///
/// This is not called if the two animations provided to the constructor have
/// the same value at the time of the call to the constructor. In that case,
/// the second animation is used from the start, and the first is ignored.
VoidCallback onSwitchedTrain;
VoidCallback? onSwitchedTrain;
AnimationStatus _lastStatus;
AnimationStatus? _lastStatus;
void _statusChangeHandler(AnimationStatus status) {
assert(_currentTrain != null);
if (status != _lastStatus) {
......@@ -539,30 +537,30 @@ class TrainHoppingAnimation extends Animation<double>
}
@override
AnimationStatus get status => _currentTrain.status;
AnimationStatus get status => _currentTrain!.status;
double _lastValue;
double? _lastValue;
void _valueChangeHandler() {
assert(_currentTrain != null);
bool hop = false;
if (_nextTrain != null) {
assert(_mode != null);
switch (_mode) {
switch (_mode!) {
case _TrainHoppingMode.minimize:
hop = _nextTrain.value <= _currentTrain.value;
hop = _nextTrain!.value <= _currentTrain!.value;
break;
case _TrainHoppingMode.maximize:
hop = _nextTrain.value >= _currentTrain.value;
hop = _nextTrain!.value >= _currentTrain!.value;
break;
}
if (hop) {
_currentTrain
_currentTrain!
..removeStatusListener(_statusChangeHandler)
..removeListener(_valueChangeHandler);
_currentTrain = _nextTrain;
_currentTrain = _nextTrain!;
_nextTrain = null;
_currentTrain.addStatusListener(_statusChangeHandler);
_statusChangeHandler(_currentTrain.status);
_currentTrain!.addStatusListener(_statusChangeHandler);
_statusChangeHandler(_currentTrain!.status);
}
}
final double newValue = value;
......@@ -572,19 +570,19 @@ class TrainHoppingAnimation extends Animation<double>
}
assert(_lastValue != null);
if (hop && onSwitchedTrain != null)
onSwitchedTrain();
onSwitchedTrain!();
}
@override
double get value => _currentTrain.value;
double get value => _currentTrain!.value;
/// Frees all the resources used by this performance.
/// After this is called, this object is no longer usable.
@override
void dispose() {
assert(_currentTrain != null);
_currentTrain.removeStatusListener(_statusChangeHandler);
_currentTrain.removeListener(_valueChangeHandler);
_currentTrain!.removeStatusListener(_statusChangeHandler);
_currentTrain!.removeListener(_valueChangeHandler);
_currentTrain = null;
_nextTrain?.removeListener(_valueChangeHandler);
_nextTrain = null;
......@@ -614,8 +612,8 @@ abstract class CompoundAnimation<T> extends Animation<T>
/// Creates a CompoundAnimation. Both arguments must be non-null. Either can
/// be a CompoundAnimation itself to combine multiple animations.
CompoundAnimation({
@required this.first,
@required this.next,
required this.first,
required this.next,
}) : assert(first != null),
assert(next != null);
......@@ -658,7 +656,7 @@ abstract class CompoundAnimation<T> extends Animation<T>
return '${objectRuntimeType(this, 'CompoundAnimation')}($first, $next)';
}
AnimationStatus _lastStatus;
AnimationStatus? _lastStatus;
void _maybeNotifyStatusListeners(AnimationStatus _) {
if (status != _lastStatus) {
_lastStatus = status;
......@@ -666,7 +664,7 @@ abstract class CompoundAnimation<T> extends Animation<T>
}
}
T _lastValue;
T? _lastValue;
void _maybeNotifyListeners() {
if (value != _lastValue) {
_lastValue = value;
......@@ -685,8 +683,8 @@ abstract class CompoundAnimation<T> extends Animation<T>
class AnimationMean extends CompoundAnimation<double> {
/// Creates an animation that tracks the mean of two other animations.
AnimationMean({
Animation<double> left,
Animation<double> right,
required Animation<double> left,
required Animation<double> right,
}) : super(first: left, next: right);
@override
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'dart:ui';
......@@ -526,7 +525,7 @@ abstract class Curve2D extends ParametricCurve<Offset> {
assert(x != null);
double start = 0.0;
double end = 1.0;
double mid;
late double mid;
double offsetToOrigin(double pos) => x - transform(pos).dx;
// Use a binary search to find the inverse point within 1e-6, or 100
// subdivisions, whichever comes first.
......@@ -626,8 +625,8 @@ class CatmullRomSpline extends Curve2D {
CatmullRomSpline(
List<Offset> controlPoints, {
double tension = 0.0,
Offset startHandle,
Offset endHandle,
Offset? startHandle,
Offset? endHandle,
}) : assert(controlPoints != null),
assert(tension != null),
assert(tension <= 1.0, 'tension $tension must not be greater than 1.0.'),
......@@ -646,8 +645,8 @@ class CatmullRomSpline extends Curve2D {
CatmullRomSpline.precompute(
List<Offset> controlPoints, {
double tension = 0.0,
Offset startHandle,
Offset endHandle,
Offset? startHandle,
Offset? endHandle,
}) : assert(controlPoints != null),
assert(tension != null),
assert(tension <= 1.0, 'tension $tension must not be greater than 1.0.'),
......@@ -663,8 +662,8 @@ class CatmullRomSpline extends Curve2D {
static List<List<Offset>> _computeSegments(
List<Offset> controlPoints,
double tension, {
Offset startHandle,
Offset endHandle,
Offset? startHandle,
Offset? endHandle,
}) {
// If not specified, select the first and last control points (which are
// handles: they are not intersected by the resulting curve) so that they
......@@ -713,17 +712,17 @@ class CatmullRomSpline extends Curve2D {
final List<List<Offset>> _cubicSegments;
// This is non-empty only if the _cubicSegments are being computed lazily.
final List<Offset> _controlPoints;
final Offset _startHandle;
final Offset _endHandle;
final double _tension;
final List<Offset>? _controlPoints;
final Offset? _startHandle;
final Offset? _endHandle;
final double? _tension;
void _initializeIfNeeded() {
if (_cubicSegments.isNotEmpty) {
return;
}
_cubicSegments.addAll(
_computeSegments(_controlPoints, _tension, startHandle: _startHandle, endHandle: _endHandle),
_computeSegments(_controlPoints!, _tension!, startHandle: _startHandle, endHandle: _endHandle),
);
}
......@@ -905,9 +904,9 @@ class CatmullRomCurve extends Curve {
/// In release mode, this function can be used to decide if a proposed
/// modification to the curve will result in a valid curve.
static bool validateControlPoints(
List<Offset> controlPoints, {
List<Offset>? controlPoints, {
double tension = 0.0,
List<String> reasons,
List<String>? reasons,
}) {
assert(tension != null);
if (controlPoints == null) {
......@@ -937,7 +936,7 @@ class CatmullRomCurve extends Curve {
(controlPoints[i].dx <= 0.0 || controlPoints[i].dx >= 1.0)) {
assert(() {
reasons?.add('Control points must have X values between 0.0 and 1.0, exclusive. '
'Point $i has an x value (${controlPoints[i].dx}) which is outside the range.');
'Point $i has an x value (${controlPoints![i].dx}) which is outside the range.');
return true;
}());
return false;
......@@ -946,7 +945,7 @@ class CatmullRomCurve extends Curve {
assert(() {
reasons?.add('Each X coordinate must be greater than the preceding X coordinate '
'(i.e. must be monotonically increasing in X). Point $i has an x value of '
'${controlPoints[i].dx}, which is not greater than $lastX');
'${controlPoints![i].dx}, which is not greater than $lastX');
return true;
}());
return false;
......@@ -1053,7 +1052,7 @@ class CatmullRomCurve extends Curve {
// Now interpolate between the found sample and the next one.
final double t2 = (t - startValue.dx) / (endValue.dx - startValue.dx);
return lerpDouble(startValue.dy, endValue.dy, t2);
return lerpDouble(startValue.dy, endValue.dy, t2)!;
}
}
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
......@@ -121,7 +120,7 @@ mixin AnimationLocalListenersMixin {
void notifyListeners() {
final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners);
for (final VoidCallback listener in localListeners) {
InformationCollector collector;
InformationCollector? collector;
assert(() {
collector = () sync* {
yield DiagnosticsProperty<AnimationLocalListenersMixin>(
......@@ -199,7 +198,7 @@ mixin AnimationLocalStatusListenersMixin {
if (_statusListeners.contains(listener))
listener(status);
} catch (exception, stack) {
InformationCollector collector;
InformationCollector? collector;
assert(() {
collector = () sync* {
yield DiagnosticsProperty<AnimationLocalStatusListenersMixin>(
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Color, Size, Rect;
......@@ -215,19 +214,22 @@ class Tween<T extends dynamic> extends Animatable<T> {
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
Tween({ this.begin, this.end });
Tween({
this.begin,
this.end,
});
/// The value this variable has at the beginning of the animation.
///
/// See the constructor for details about whether this property may be null
/// (it varies from subclass to subclass).
T begin;
T? begin;
/// The value this variable has at the end of the animation.
///
/// See the constructor for details about whether this property may be null
/// (it varies from subclass to subclass).
T end;
T? end;
/// Returns the value this variable has at the given animation clock value.
///
......@@ -256,9 +258,9 @@ class Tween<T extends dynamic> extends Animatable<T> {
@override
T transform(double t) {
if (t == 0.0)
return begin;
return begin as T;
if (t == 1.0)
return end;
return end as T;
return lerp(t);
}
......@@ -290,7 +292,7 @@ class ReverseTween<T> extends Tween<T> {
/// [Color.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class ColorTween extends Tween<Color> {
class ColorTween extends Tween<Color?> {
/// Creates a [Color] tween.
///
/// The [begin] and [end] properties may be null; the null value
......@@ -300,11 +302,11 @@ class ColorTween extends Tween<Color> {
/// or [end] if you want the effect of fading in or out of transparent.
/// Instead prefer null. [Colors.transparent] refers to black transparent and
/// thus will fade out of or into black which is likely unwanted.
ColorTween({ Color begin, Color end }) : super(begin: begin, end: end);
ColorTween({ Color? begin, Color? end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Color lerp(double t) => Color.lerp(begin, end, t);
Color? lerp(double t) => Color.lerp(begin, end, t);
}
/// An interpolation between two sizes.
......@@ -313,16 +315,16 @@ class ColorTween extends Tween<Color> {
/// [Size.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class SizeTween extends Tween<Size> {
class SizeTween extends Tween<Size?> {
/// Creates a [Size] tween.
///
/// The [begin] and [end] properties may be null; the null value
/// is treated as an empty size.
SizeTween({ Size begin, Size end }) : super(begin: begin, end: end);
SizeTween({ Size? begin, Size? end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Size lerp(double t) => Size.lerp(begin, end, t);
Size? lerp(double t) => Size.lerp(begin, end, t);
}
/// An interpolation between two rectangles.
......@@ -331,16 +333,16 @@ class SizeTween extends Tween<Size> {
/// [Rect.lerp].
///
/// See [Tween] for a discussion on how to use interpolation objects.
class RectTween extends Tween<Rect> {
class RectTween extends Tween<Rect?> {
/// Creates a [Rect] tween.
///
/// The [begin] and [end] properties may be null; the null value
/// is treated as an empty rect at the top left corner.
RectTween({ Rect begin, Rect end }) : super(begin: begin, end: end);
RectTween({ Rect? begin, Rect? end }) : super(begin: begin, end: end);
/// Returns the value this variable has at the given animation clock value.
@override
Rect lerp(double t) => Rect.lerp(begin, end, t);
Rect? lerp(double t) => Rect.lerp(begin, end, t);
}
/// An interpolation between two integers that rounds.
......@@ -360,12 +362,12 @@ class IntTween extends Tween<int> {
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
IntTween({ int begin, int end }) : super(begin: begin, end: end);
IntTween({ int? begin, int? end }) : super(begin: begin, end: end);
// The inherited lerp() function doesn't work with ints because it multiplies
// the begin and end types by a double, and int * double returns a double.
@override
int lerp(double t) => (begin + (end - begin) * t).round();
int lerp(double t) => (begin! + (end! - begin!) * t).round();
}
/// An interpolation between two integers that floors.
......@@ -385,12 +387,12 @@ class StepTween extends Tween<int> {
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
StepTween({ int begin, int end }) : super(begin: begin, end: end);
StepTween({ int? begin, int? end }) : super(begin: begin, end: end);
// The inherited lerp() function doesn't work with ints because it multiplies
// the begin and end types by a double, and int * double returns a double.
@override
int lerp(double t) => (begin + (end - begin) * t).floor();
int lerp(double t) => (begin! + (end! - begin!) * t).floor();
}
/// A tween with a constant value.
......@@ -400,7 +402,7 @@ class ConstantTween<T> extends Tween<T> {
/// This tween doesn't interpolate, it always returns the same value.
@override
T lerp(double t) => begin;
T lerp(double t) => begin as T;
@override
String toString() => '${objectRuntimeType(this, 'ReverseTween')}(value: $begin)';
......@@ -436,7 +438,7 @@ class CurveTween extends Animatable<double> {
/// Creates a curve tween.
///
/// The [curve] argument must not be null.
CurveTween({ @required this.curve })
CurveTween({ required this.curve })
: assert(curve != null);
/// The curve to use when transforming the value of the animation.
......
......@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'animation.dart';
import 'tween.dart';
......@@ -90,8 +87,7 @@ class TweenSequence<T> extends Animatable<T> {
return _evaluateAt(t, index);
}
// Should be unreachable.
assert(false, 'TweenSequence.evaluate() could not find an interval for $t');
return null;
throw StateError('TweenSequence.evaluate() could not find an interval for $t');
}
@override
......@@ -128,8 +124,8 @@ class TweenSequenceItem<T> {
///
/// The [tween] must not be null and [weight] must be greater than 0.0.
const TweenSequenceItem({
@required this.tween,
@required this.weight,
required this.tween,
required this.weight,
}) : assert(tween != null),
assert(weight != null),
assert(weight > 0.0);
......
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