From fc978c1aa81b01ba704f13d1043f4584bf89180d Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 19 Jan 2016 15:41:15 -0800 Subject: [PATCH] Port examples to the new animation API These now use Animation and AnimationController instead of PerformanceView and Performance. --- .../lib/demo/page_selector_demo.dart | 14 +-- examples/widgets/progress_indicator.dart | 2 +- examples/widgets/smooth_resize.dart | 43 +++++---- packages/flutter/lib/src/animation/tween.dart | 16 ++-- packages/flutter/lib/src/material/tabs.dart | 87 ++++++++++--------- .../src/widgets/enter_exit_transition.dart | 28 +++--- 6 files changed, 95 insertions(+), 95 deletions(-) diff --git a/examples/material_gallery/lib/demo/page_selector_demo.dart b/examples/material_gallery/lib/demo/page_selector_demo.dart index 274e9fac808..f7caf538f9c 100644 --- a/examples/material_gallery/lib/demo/page_selector_demo.dart +++ b/examples/material_gallery/lib/demo/page_selector_demo.dart @@ -12,21 +12,21 @@ final List _iconNames = ["event", "home", "android", "alarm", "f class TabViewDemo extends StatelessComponent { Widget _buildTabIndicator(BuildContext context, String iconName) { final Color color = Theme.of(context).primaryColor; - final AnimatedColorValue _selectedColor = new AnimatedColorValue(Colors.transparent, end: color, curve: Curves.ease); - final AnimatedColorValue _previousColor = new AnimatedColorValue(color, end: Colors.transparent, curve: Curves.ease); + final ColorTween _selectedColor = new ColorTween(begin: Colors.transparent, end: color); + final ColorTween _previousColor = new ColorTween(begin: color, end: Colors.transparent); final TabBarSelectionState selection = TabBarSelection.of(context); - return new BuilderTransition( - performance: selection.performance, - variables: [_selectedColor, _previousColor], + Animation animation = new CurvedAnimation(parent: selection.animation, curve: Curves.ease); + return new AnimationWatchingBuilder( + watchable: animation, builder: (BuildContext context) { Color background = selection.value == iconName ? _selectedColor.end : _selectedColor.begin; if (selection.valueIsChanging) { // Then the selection's performance is animating from previousValue to value. if (selection.value == iconName) - background = _selectedColor.value; + background = _selectedColor.evaluate(animation); else if (selection.previousValue == iconName) - background = _previousColor.value; + background = _previousColor.evaluate(animation); } return new Container( width: 12.0, diff --git a/examples/widgets/progress_indicator.dart b/examples/widgets/progress_indicator.dart index a9f8c389986..b6171d90f2e 100644 --- a/examples/widgets/progress_indicator.dart +++ b/examples/widgets/progress_indicator.dart @@ -16,7 +16,7 @@ class _ProgressIndicatorAppState extends State { duration: const Duration(milliseconds: 1500) )..play(AnimationDirection.forward); - animation = new ACurve( + animation = new CurvedAnimation( parent: controller, curve: new Interval(0.0, 0.9, curve: Curves.ease), reverseCurve: Curves.ease diff --git a/examples/widgets/smooth_resize.dart b/examples/widgets/smooth_resize.dart index bd4c66c9c06..2d786860ce7 100644 --- a/examples/widgets/smooth_resize.dart +++ b/examples/widgets/smooth_resize.dart @@ -26,29 +26,28 @@ class SmoothBlock extends StatefulComponent { class CardTransition extends StatelessComponent { CardTransition({ this.child, - this.performance, + this.animation, this.x, this.opacity, this.scale }); final Widget child; - final Performance performance; - final AnimatedValue x; - final AnimatedValue opacity; - final AnimatedValue scale; + final Animation animation; + final Evaluatable x; + final Evaluatable opacity; + final Evaluatable scale; Widget build(BuildContext context) { - - return new BuilderTransition( - performance: performance, - variables: >[x, opacity, scale], + return new AnimationWatchingBuilder( + watchable: animation, builder: (BuildContext context) { + double currentScale = scale.evaluate(animation); Matrix4 transform = new Matrix4.identity() - ..translate(x.value) - ..scale(scale.value, scale.value); + ..translate(x.evaluate(animation)) + ..scale(currentScale, currentScale); return new Opacity( - opacity: opacity.value, + opacity: opacity.evaluate(animation), child: new Transform( transform: transform, child: child @@ -63,22 +62,22 @@ class SmoothBlockState extends State { double _height = 100.0; - Widget _handleEnter(PerformanceView performance, Widget child) { + Widget _handleEnter(Animation animation, Widget child) { return new CardTransition( - x: new AnimatedValue(-200.0, end: 0.0, curve: Curves.ease), - opacity: new AnimatedValue(0.0, end: 1.0, curve: Curves.ease), - scale: new AnimatedValue(0.8, end: 1.0, curve: Curves.ease), - performance: performance, + x: new Tween(begin: -200.0, end: 0.0), + opacity: new Tween(begin: 0.0, end: 1.0), + scale: new Tween(begin: 0.8, end: 1.0), + animation: new CurvedAnimation(parent: animation, curve: Curves.ease), child: child ); } - Widget _handleExit(PerformanceView performance, Widget child) { + Widget _handleExit(Animation animation, Widget child) { return new CardTransition( - x: new AnimatedValue(0.0, end: 200.0, curve: Curves.ease), - opacity: new AnimatedValue(1.0, end: 0.0, curve: Curves.ease), - scale: new AnimatedValue(1.0, end: 0.8, curve: Curves.ease), - performance: performance, + x: new Tween(begin: 0.0, end: 200.0), + opacity: new Tween(begin: 1.0, end: 0.0), + scale: new Tween(begin: 1.0, end: 0.8), + animation: new CurvedAnimation(parent: animation, curve: Curves.ease), child: child ); } diff --git a/packages/flutter/lib/src/animation/tween.dart b/packages/flutter/lib/src/animation/tween.dart index f95485334d1..046a2d36f2e 100644 --- a/packages/flutter/lib/src/animation/tween.dart +++ b/packages/flutter/lib/src/animation/tween.dart @@ -92,7 +92,7 @@ abstract class ProxyWatchableMixin implements Watchable { abstract class Evaluatable { const Evaluatable(); - T evaluate(double t); + T evaluate(Animation animation); WatchableValue watch(Animation parent) { return new WatchableValue(parent: parent, evaluatable: this); @@ -105,7 +105,7 @@ class WatchableValue extends Watchable with ProxyWatchableMixin { final Animation parent; final Evaluatable evaluatable; - T get value => evaluatable.evaluate(parent.progress); + T get value => evaluatable.evaluate(parent); } abstract class Animation extends Watchable { @@ -261,9 +261,8 @@ class _RepeatingSimulation extends Simulation { bool isDone(double timeInSeconds) => false; } -// TODO(abarth): Rename Curve to UnitTransform and ACurve to Curve. -class ACurve extends Animation with ProxyWatchableMixin { - ACurve({ this.parent, this.curve, this.reverseCurve }) { +class CurvedAnimation extends Animation with ProxyWatchableMixin { + CurvedAnimation({ this.parent, this.curve, this.reverseCurve }) { assert(parent != null); assert(curve != null); parent.addStatusListener(_handleStatusChanged); @@ -317,9 +316,7 @@ class ACurve extends Animation with ProxyWatchableMixin { } class Tween extends Evaluatable { - Tween({ this.begin, this.end }) { - assert(begin != null); - } + Tween({ this.begin, this.end }); /// The value this variable has at the beginning of the animation. T begin; @@ -330,9 +327,10 @@ class Tween extends Evaluatable { /// Returns the value this variable has at the given animation clock value. T lerp(double t) => begin + (end - begin) * t; - T evaluate(double t) { + T evaluate(Animation animation) { if (end == null) return begin; + double t = animation.progress; if (t == 0.0) return begin; if (t == 1.0) diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index a2ba0a68f00..feb5d998554 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -415,10 +415,10 @@ class TabBarSelection extends StatefulComponent { class TabBarSelectionState extends State> { - PerformanceView get performance => _performance.view; + Animation get animation => _controller.view; // Both the TabBar and TabBarView classes access _performance because they // alternately drive selection progress between tabs. - final _performance = new Performance(duration: _kTabBarScroll, progress: 1.0); + final AnimationController _controller = new AnimationController(duration: _kTabBarScroll, progress: 1.0); final Map _valueToIndex = new Map(); void _initValueToIndex() { @@ -442,7 +442,7 @@ class TabBarSelectionState extends State> { } void dispose() { - _performance.stop(); + _controller.stop(); PageStorage.of(context)?.writeState(context, _value); super.dispose(); } @@ -481,21 +481,21 @@ class TabBarSelectionState extends State> { // the previous and current selection index. double progress; - if (_performance.status == PerformanceStatus.completed) + if (_controller.status == PerformanceStatus.completed) progress = 0.0; else if (_previousValue == values.first) - progress = _performance.progress; + progress = _controller.progress; else if (_previousValue == values.last) - progress = 1.0 - _performance.progress; + progress = 1.0 - _controller.progress; else if (previousIndex < index) - progress = (_performance.progress - 0.5) * 2.0; + progress = (_controller.progress - 0.5) * 2.0; else - progress = 1.0 - _performance.progress * 2.0; + progress = 1.0 - _controller.progress * 2.0; - _performance + _controller ..progress = progress ..forward().then((_) { - if (_performance.progress == 1.0) { + if (_controller.progress == 1.0) { if (config.onChanged != null) config.onChanged(_value); _valueIsChanging = false; @@ -507,14 +507,14 @@ class TabBarSelectionState extends State> { void registerPerformanceListener(TabBarSelectionPerformanceListener listener) { _performanceListeners.add(listener); - _performance + _controller ..addStatusListener(listener.handleStatusChange) ..addListener(listener.handleProgressChange); } void unregisterPerformanceListener(TabBarSelectionPerformanceListener listener) { _performanceListeners.remove(listener); - _performance + _controller ..removeStatusListener(listener.handleStatusChange) ..removeListener(listener.handleProgressChange); } @@ -590,17 +590,11 @@ class _TabBarState extends ScrollableState> implements TabBarSelect if (_valueIsChanging && status == PerformanceStatus.completed) { _valueIsChanging = false; - double progress = 0.5; - if (_selection.index == 0) - progress = 0.0; - else if (_selection.index == config.labels.length - 1) - progress = 1.0; + _indicatorTween + ..begin = _tabIndicatorRect(math.max(0, _selection.index - 1)) + ..end = _tabIndicatorRect(math.min(config.labels.length - 1, _selection.index + 1)); setState(() { - _indicatorRect - ..begin = _tabIndicatorRect(math.max(0, _selection.index - 1)) - ..end = _tabIndicatorRect(math.min(config.labels.length - 1, _selection.index + 1)) - ..curve = null - ..setProgress(progress, AnimationDirection.forward); + _indicatorRect = _tabIndicatorRect(_selection.index); }); } } @@ -612,23 +606,32 @@ class _TabBarState extends ScrollableState> implements TabBarSelect if (!_valueIsChanging && _selection.valueIsChanging) { if (config.isScrollable) scrollTo(_centeredTabScrollOffset(_selection.index), duration: _kTabBarScroll); - _indicatorRect - ..begin = _indicatorRect.value ?? _tabIndicatorRect(_selection.previousIndex) - ..end = _tabIndicatorRect(_selection.index) - ..curve = Curves.ease; + _indicatorTween + ..begin = _indicatorRect ?? _tabIndicatorRect(_selection.previousIndex) + ..end = _tabIndicatorRect(_selection.index); _valueIsChanging = true; } - Rect oldRect = _indicatorRect.value; - _indicatorRect.setProgress(_selection.performance.progress, AnimationDirection.forward); - Rect newRect = _indicatorRect.value; - if (oldRect != newRect) + Rect oldRect = _indicatorRect; + double t = _selection.animation.progress; + if (_valueIsChanging) { + // When _valueIsChanging is true, we're animating based on a ticker and + // want to curve the animation. When _valueIsChanging is false, we're + // animating based on a pointer event and want linear feedback. It's + // possible we should move this curve into the selection animation. + t = Curves.ease.transform(t); + } + // TODO(abarth): If we've never gone through handleStatusChange before, we + // might not have set up our _indicatorTween yet. + _indicatorRect = _indicatorTween.lerp(t); + if (oldRect != _indicatorRect) setState(() { }); } Size _viewportSize = Size.zero; Size _tabBarSize; List _tabWidths; - AnimatedRectValue _indicatorRect = new AnimatedRectValue(null); + Rect _indicatorRect; + RectTween _indicatorTween = new RectTween(); Rect _tabRect(int tabIndex) { assert(_tabBarSize != null); @@ -673,9 +676,9 @@ class _TabBarState extends ScrollableState> implements TabBarSelect labelColor = isSelectedTab ? selectedColor : color; if (_selection.valueIsChanging) { if (isSelectedTab) - labelColor = Color.lerp(color, selectedColor, _selection.performance.progress); + labelColor = Color.lerp(color, selectedColor, _selection.animation.progress); else if (isPreviouslySelectedTab) - labelColor = Color.lerp(selectedColor, color, _selection.performance.progress); + labelColor = Color.lerp(selectedColor, color, _selection.animation.progress); } } return new _Tab( @@ -749,7 +752,7 @@ class _TabBarState extends ScrollableState> implements TabBarSelect children: tabs, selectedIndex: _selection?.index, indicatorColor: indicatorColor, - indicatorRect: _indicatorRect.value, + indicatorRect: _indicatorRect, textAndIcons: textAndIcons, isScrollable: config.isScrollable, onLayoutChanged: _layoutChanged @@ -873,14 +876,14 @@ class _TabBarViewState extends PageableListState implements TabBarSe return; // The TabBar is driving the TabBarSelection performance. - final Performance performance = _selection.performance; + final Animation animation = _selection.animation; - if (performance.status == PerformanceStatus.completed) { + if (animation.status == PerformanceStatus.completed) { _updateItemsAndScrollBehavior(); return; } - if (performance.status != PerformanceStatus.forward) + if (animation.status != PerformanceStatus.forward) return; final int selectedIndex = _selection.index; @@ -895,9 +898,9 @@ class _TabBarViewState extends PageableListState implements TabBarSe } if (_scrollDirection == AnimationDirection.forward) - scrollTo(performance.progress); + scrollTo(animation.progress); else - scrollTo(1.0 - performance.progress); + scrollTo(1.0 - animation.progress); } void dispatchOnScroll() { @@ -905,12 +908,12 @@ class _TabBarViewState extends PageableListState implements TabBarSe return; // This class is driving the TabBarSelection's performance. - final Performance performance = _selection._performance; + final AnimationController controller = _selection._controller; if (_selection.index == 0 || _selection.index == _tabCount - 1) - performance.progress = scrollOffset; + controller.progress = scrollOffset; else - performance.progress = scrollOffset / 2.0; + controller.progress = scrollOffset / 2.0; } Future fling(Offset scrollVelocity) { diff --git a/packages/flutter/lib/src/widgets/enter_exit_transition.dart b/packages/flutter/lib/src/widgets/enter_exit_transition.dart index 8c4dbe687c5..db851eb2401 100644 --- a/packages/flutter/lib/src/widgets/enter_exit_transition.dart +++ b/packages/flutter/lib/src/widgets/enter_exit_transition.dart @@ -70,30 +70,30 @@ class _SmoothlyResizingOverflowBoxState extends State exitTransition ?? enterTransition; void dispose() { - enterPerformance?.stop(); - exitPerformance?.stop(); + enterController?.stop(); + exitController?.stop(); } } -typedef Widget TransitionBuilderCallback(PerformanceView performance, Widget child); +typedef Widget TransitionBuilderCallback(Animation animation, Widget child); -Widget _identityTransition(PerformanceView performance, Widget child) => child; +Widget _identityTransition(Animation animation, Widget child) => child; class EnterExitTransition extends StatefulComponent { EnterExitTransition({ @@ -129,11 +129,11 @@ class _EnterExitTransitionState extends State { } _Entry _createEnterTransition() { - Performance enterPerformance = new Performance(duration: config.duration)..play(); + AnimationController enterController = new AnimationController(duration: config.duration)..forward(); return new _Entry( child: config.child, - enterPerformance: enterPerformance, - enterTransition: config.onEnter(enterPerformance, new KeyedSubtree( + enterController: enterController, + enterTransition: config.onEnter(enterController, new KeyedSubtree( key: new GlobalKey(), child: config.child )) @@ -141,11 +141,11 @@ class _EnterExitTransitionState extends State { } Future _createExitTransition(_Entry entry) async { - Performance exitPerformance = new Performance(duration: config.duration); + AnimationController exitController = new AnimationController(duration: config.duration); entry - ..exitPerformance = exitPerformance - ..exitTransition = config.onExit(exitPerformance, entry.enterTransition); - await exitPerformance.play(); + ..exitController = exitController + ..exitTransition = config.onExit(exitController, entry.enterTransition); + await exitController.forward(); if (!mounted) return; setState(() {