diff --git a/_data/sidebars/home_sidebar.yml b/_data/sidebars/home_sidebar.yml index b52b0434ebf..a40975a3ce9 100644 --- a/_data/sidebars/home_sidebar.yml +++ b/_data/sidebars/home_sidebar.yml @@ -17,7 +17,7 @@ entries: - title: Flutter Examples external_url: https://github.com/flutter/flutter/tree/master/examples output: web - + - title: New to Flutter output: web folderitems: @@ -98,6 +98,10 @@ entries: url: /text-input/ output: web + - title: Animate Widgets + url: /animating-widgets/ + output: web + - title: Helpful Resources output: web folderitems: diff --git a/animating-widgets.md b/animating-widgets.md new file mode 100644 index 00000000000..ae93fabe9c5 --- /dev/null +++ b/animating-widgets.md @@ -0,0 +1,293 @@ +--- +layout: page +title: Animating Widgets +sidebar: home_sidebar +permalink: /animating-widgets/ +--- + +This guide shows some common ways you can add animation +effects to your apps using Flutter’s animation system. + +* TOC +{:toc} + +## Introduction + +You can use animations to make the user experience on your mobile app feel more +intuitive, dynamic, and polished. Animations are especially useful when the +screen changes state, such as when content loads or when new actions become +available. + +The [`flutter/animation`](https://docs.flutter.io/flutter/animation/animation-library.html) +package in the Flutter SDK provides APIs to create animation effects in user +interfaces (UIs) that are built on the +[`StatelessWidget`](https://docs.flutter.io/flutter/widgets/StatelessWidget-class.html) +and [`StatefulWidget`](https://docs.flutter.io/flutter/widgets/StatefulWidget-class.html) +classes. + +Animations in Flutter are encapsulated as +[`Animation`](https://docs.flutter.io/flutter/animation/Animation-class.html) +objects that contain these key properties: + ++ **Value:** The animation object’s typed value represents a data point within +a range (also called an interpolation). You can define an animation class to +generate values based on a given functional mapping, such as a linear, curve, +or step-wise function. ++ **Status:** The animation object’s current status (such as forward, +backward, completed, and dismissed), as listed by the +[`AnimationStatus`](https://docs.flutter.io/flutter/animation/AnimationStatus-class.html) +constants. + +To create an animation effect in your app, you need to write code to do the +following: + +1. Attach an animation object to a widget or a listener to detect changes to the +animation object. +2. Specify how the the animation is *interpolated* (that is, how the animation +objects’s value and status changes over +time) as it runs. + +Based on the animation object’s properties at a specific frame, Flutter +dynamically modifies your widget visual appearence, and rebuilds the widget +tree to produce visual transitions such as sliding, scaling, rotation, height +or width changes, and fading. + +Flutter's flexible animation model allows you to define interpolations for +spatial positioning, color gradients, image scaling, and others. You can define +your own subclass of +[`Animation`](https://docs.flutter.io/flutter/animation/Animation-class.html) +or use an animation subclass that the framework provides. + +To learn more about +using the other key classes in the +[`flutter/animation`](https://docs.flutter.io/flutter/animation/animation-library.html) +package, see the [Animations in Flutter](/animations) guide. + +## Render a basic widget animation + +To render your widget with an animation, set one or more of the widget’s +members to the animation object, then use the animation’s value to decide how +to draw your object. + +If you are animating a stateful widget, you can notify your widget of changes +to the animation’s values by using the +[`addListener()`](https://docs.flutter.io/flutter/animation/Animation/addListener.html) +method. The framework invokes the listener callback whenever the value of the +animation changes. Typically, you’ll want to call the +[`setState()`](http://docs.flutter.io/flutter/material/State/setState.html) +method when the animation value change occurs, to trigger the framework to +rebuild the widget tree. + +The following code snippet shows how you might create a simple animation +effect to make an logo image appear to expand. + +```dart +import 'package:flutter/material.dart'; +import 'package:flutter/animation.dart'; + +class LogoApp extends StatefulWidget { + LogoAppState createState() => new LogoAppState(); +} + +class LogoAppState extends State { + Animation animation; + + initState() { + AnimationController controller = new AnimationController( + duration: const Duration(milliseconds: 5000) + ); + animation = new Tween(begin: 0.0, end: 200.0).animate(controller); + animation.addListener(() { + setState(() { + // the state that has changed here is the animation object’s value + }); + }); + controller.forward(); + super.initState(); + } + + Widget build(BuildContext context) { + return new Center( + child: new Container( + margin: new EdgeInsets.symmetric(vertical: 10.0), + height: animation.value, + width: animation.value, + child: new AssetImage( + name: 'assets/flutter_logo.png', + fit: ImageFit.contain + ) + ) + ); + } +} + +void main() { + runApp( + new MaterialApp( + title: 'My Animation Test', + routes: { + '/': (BuildContext context) => new LogoApp() + } + ) + ); +} +``` + +You can simplify the code snippet above further by using the +[`AnimatedWidget`](http://docs.flutter.io/flutter/material/AnimatedWidget-class.html) +class. This class hides the state object and listener you previously had to +implement to run the animation. + +```dart +import 'package:flutter/material.dart'; +import 'package:flutter/animation.dart'; + +class LogoApp extends AnimatedWidget { + LogoApp({Key key, Animation animation}) + : super(key: key, animation: animation); + + Widget build(BuildContext context) { + return new Center( + child: new Container( + margin: new EdgeInsets.symmetric(vertical: 10.0), + height: animation.value, + width: animation.value, + child: new AssetImage( + name: 'assets/flutter_logo.png', + fit: ImageFit.contain + ) + ) + ); + } +} + +void main() { + final AnimationController controller = new AnimationController( + duration: const Duration(milliseconds: 5000) + ); + final animation = new Tween( + begin: 0.0, + end: 200.0) + .animate(controller); + runApp( + new MaterialApp( + title: 'My Animation Test', + routes: { + '/': (BuildContext context) => new LogoApp( + animation: animation + ) + } + ) + ); + controller.forward(); +} +``` + +For more complex animations involving additional state, consider using the +[`AnimatedBuilder`](http://docs.flutter.io/flutter/material/AnimatedBuilder-class.html) +class. + +## Render simultaneous widget animations + +The following example shows how you can apply two simultaneous animation +effects: one that controls the size of the widget and another that controls +the opacity to fade the widget in and out. + +You can use the +[`addStatusListener()`](http://docs.flutter.io/flutter/animation/Animation/addStatusListener.html) +method to notify your widget when the current status of an animation changes. +In this example, we use the status listener to switch the animation’s playback +between going forward or reverse. + +```dart +import 'package:flutter/material.dart'; +import 'package:flutter/animation.dart'; + +class LogoApp extends AnimatedWidget { + + // Declare the Tween objects as static because we don't change them. + static final _opacityTween = new Tween(begin: 1.0, end: 0.3); + static final _sizeTween = new Tween(begin: 0.0, end: 300.0); + + LogoApp({Key key, Animation animation}) + : super(key: key, animation: animation); + + Widget build(BuildContext context) { + return new Center( + child: new Opacity( + opacity: _opacityTween.evaluate(animation), + child: new Container( + margin: new EdgeInsets.symmetric(vertical: 10.0), + height: _sizeTween.evaluate(animation), + width: _sizeTween.evaluate(animation), + child: new AssetImage( + name: 'assets/flutter_logo.png', + fit: ImageFit.contain + ) + ) + ) + ); + } +} + +void main() { + final AnimationController controller = new AnimationController( + duration: const Duration(milliseconds: 5000) + ); + + final Animation animation = + new CurvedAnimation(parent: controller, curve: Curves.bounceIn); + + animation.addStatusListener((status) { + if (status == AnimationStatus.completed) + controller.reverse(); + else if (status == AnimationStatus.dismissed) + controller.forward(); + }); + + runApp( + new MaterialApp( + title: 'My Animation Test', + routes: { + '/': (BuildContext context) => new LogoApp( + animation: animation + ) + } + ) + ); + controller.forward(); +} +``` + +## Dispose your widget animation + +It’s good practice to dispose your animation controller and free up your +resources when they are no longer needed. To do so, call the +[`dispose()`](http://docs.flutter.io/flutter/material/AnimationController/dispose.html) +method on the +[`AnimationController`](http://docs.flutter.io/flutter/material/AnimationController-class.html) +object for the animation object you want to free. This stops the animation from +running. + +The following snippet shows how to call the animation controller’s +[`dispose()`](http://docs.flutter.io/flutter/material/AnimationController/dispose.html) +method from within a +[`State`](http://docs.flutter.io/flutter/material/State-class.html) object’s +[`dispose()`](http://docs.flutter.io/flutter/material/State/dispose.html) method +implementation. The framework typically invokes the +[`State`](http://docs.flutter.io/flutter/material/State-class.html) +object’s [`dispose()`](http://docs.flutter.io/flutter/material/State/dispose.html) +method when switching between screens, as directed by the routes property. + +```dart +class LogoAppState extends State { + + // Implementation code omitted for brevity. + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } +} +``` diff --git a/animations.md b/animations.md index 644787540d6..bf3820a005d 100644 --- a/animations.md +++ b/animations.md @@ -8,7 +8,7 @@ permalink: /animations/ * TOC Placeholder {:toc} -# Introduction +## Introduction The animation system in Flutter is based on typed [`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) @@ -17,19 +17,26 @@ functions directly by reading their current value and listening to their state changes or they can use the animations as the basis of more elaborate animations that they pass along to other widgets. -## Animation +## Key animation classes + +This section describes some of the common APIs you will use for creating +animation effects and controlling how they run. + +### Animation The primary building block of the animation system is the [`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) -class. An animation represents a value of a specific type that can change +class. An animation represents a value of a specific type that can change over the lifetime of the animation. Most widgets that perform an animation -receive an `Animation` object as a parameter, from which they read the current -value of the animation and to which they listen for changes to that value. +receive an [`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) +object as a parameter, from which they read the current value of the animation +and to which they listen for changes to that value. -### `addListener` +Two key methods of this class are: -Whenever the animation's value changes, the animation notifies all the -listeners added with ++ **[`addListener()`](http://docs.flutter.io/flutter/animation/Animation/addListener.html):** +Whenever the animation's value changes, the animation +notifies all the listeners added with [`addListener`](http://docs.flutter.io/flutter/animation/Animation/addListener.html). Typically, a [`State`](http://docs.flutter.io/flutter/widgets/State-class.html) object that listens to an animation will call @@ -37,7 +44,7 @@ object that listens to an animation will call itself in its listener callback to notify the widget system that it needs to rebuild with the new value of the animation. -This pattern is so common that there are two widgets that help widgets rebuild + This pattern is so common that there are two widgets that help widgets rebuild when animations change value: [`AnimatedWidget`](http://docs.flutter.io/flutter/widgets/AnimatedWidget-class.html) and @@ -49,8 +56,7 @@ function. The second, `AnimatedBuilder`, is useful for more complex widgets that wish to include an animation as part of a larger build function. To use `AnimatedBuilder`, simply construct the widget and pass it a `builder` function. -### `addStatusListener` - ++ **[`addStatusListener()`](http://docs.flutter.io/flutter/animation/Animation/addStatusListener.html):** Animations also provide an [`AnimationStatus`](http://docs.flutter.io/flutter/animation/AnimationStatus-class.html), which indicates how the animation will evolve over time. Whenever the animation's @@ -63,20 +69,35 @@ to 1.0 will be `dismissed` when their value is 0.0. An animation might then run 0.0). Eventually, if the animation reaches the end of its range (e.g., 1.0), the animation reaches the `completed` status. -## AnimationController +### AnimationController -To create an animation, first create an -[`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html). -As well as being an animation itself, an `AnimationController` lets you control -the animation. For example, you can tell the controller to play the animation +Use the [`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html) +class to specify how an animation should run. The +[`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html) +class lets you define important characteristics of the animation, such as its +duration and playback direction (forward or reverse). + +The following snippet shows how you might create an animation that runs for +500 milliseconds: + +```dart +final AnimationController controller = new AnimationController( + duration: const Duration(milliseconds: 500) +); +``` + +As well as being an animation itself, an +[`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html) +lets you control the animation. For example, you can tell the controller to play the animation [`forward`](http://docs.flutter.io/flutter/animation/AnimationController/forward.html) or [`stop`](http://docs.flutter.io/flutter/animation/AnimationController/stop.html) -the animation and later -[`resume`](http://docs.flutter.io/flutter/animation/AnimationController/resume.html) +the animation and later [`resume`](http://docs.flutter.io/flutter/animation/AnimationController/resume.html) it. You can also [`fling`](http://docs.flutter.io/flutter/animation/AnimationController/fling.html) animations, which uses a physical simulation, such as a spring, to drive the animation. +To create an animation, first create an +[`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html). Once you've created an animation controller, you can start building other animations based on it. For example, you can create a [`ReverseAnimation`](http://docs.flutter.io/flutter/animation/ReverseAnimation-class.html) @@ -85,7 +106,90 @@ from 1.0 to 0.0). Similarly, you can create a [`CurvedAnimation`](http://docs.flutter.io/flutter/animation/CurvedAnimation-class.html) whose value is adjusted by a [curve](http://docs.flutter.io/flutter/animation/Curves-class.html). -## Tweens +### CurvedAnimation + +Use the [`CurvedAnimation`](http://docs.flutter.io/flutter/material/CurvedAnimation-class.html) +class to apply a non-linear curve to an animation object it wraps. +By applying different curve types, you can visually modify the spatial movement +pattern for the wrapped animation object. + +The +[`Curves`](http://docs.flutter.io/flutter/animation/Curves-class.html) class +lists the available curve types, such as +[`bounceIn`](http://docs.flutter.io/flutter/animation/Curves/bounceIn-constant.html), +[`easeOut`](http://docs.flutter.io/flutter/animation/Curves/easeOut-constant.html), +and others. + +The following snippet shows how you might create a curved animation object that +wraps a linear animation produced by an animation controller and applies the +[`easeIn`](http://docs.flutter.io/flutter/animation/Curves/easeIn-constant.html) +curve type to it. + +```dart +final AnimationController controller = + new AnimationController(duration: const Duration(milliseconds: 500)); + +final curve = new CurvedAnimation( + parent: controller, + curve: Curves.easeIn +); +``` + +### Tween + +The [`Tween`](http://docs.flutter.io/flutter/material/Tween-class.html) class +represents a changing value between a range with a +[`begin`](http://docs.flutter.io/flutter/material/Tween/begin.html) and +[`end`](http://docs.flutter.io/flutter/material/Tween/end.html) value. To get +the interpolated value for a given animation, call the +[`evaluate()`](http://docs.flutter.io/flutter/animation/Tween/evaluate.html) +method on the Tween object. You can override the +[`lerp()`](http://docs.flutter.io/flutter/material/Tween/lerp.html) +(or *linear interpolation*) method for the +[`Tween`](http://docs.flutter.io/flutter/material/Tween-class.html) object, +which returns a value based on a given animation clock time. + +You can use these subclasses of +[`Tween`](http://docs.flutter.io/flutter/material/Tween-class.html) to apply +specialized interpolations to your animations: + ++ [`ColorTween`](http://docs.flutter.io/flutter/animation/ColorTween-class.html): +Interpolation between colors. ++ [`SizeTween`](https://docs.flutter.io/flutter/animation/SizeTween-class.html): +Interpolation between rectangle sizes. ++ [`ThemeDataTween`](https://docs.flutter.io/flutter/material/ThemeDataTween-class.html): +Interpolation between +[`ThemeData`](https://docs.flutter.io/flutter/material/ThemeData-class.html) objects. + +The following snippet shows how you might create a +[`Tween`](http://docs.flutter.io/flutter/material/Tween-class.html) object that +interpolates between the double values of -200.0 to 0.0. + +```dart +final Tween doubleTween = new Tween(begin: -200.0, end: 0.0); +``` + +You can also specify a progression between two colors. For example: + +```dart +final Tween colorTween = + new ColorTween(begin: Colors.transparent, end: Colors.black54); +``` + +To apply a Tween to a given animation object, use the [`animate()`]() +method which returns a new Animation instance. For example, the following code +snippet shows how you might create an animation represented by integral values +from 0 to 255, over a duration of 500 milliseconds, using linear interpolation. + +```dart +final AnimationController animation = + new AnimationController(duration: const Duration(milliseconds: 500)); + +Animation alpha = new IntTween( + begin: 0, + end: 255) +.animate(animation); +``` To animate beyond the 0.0 to 1.0 interval, you can use a [`Tween`](http://docs.flutter.io/flutter/animation/Tween-class.html), which @@ -104,26 +208,24 @@ function. By itself, a tween just defines how to interpolate between two values. To get a concrete value for the current frame of an animation, you also need an -animation to determine the current state. There are two ways to combine a tween -with an animation to get a concrete value: - -1. You can [`evaluate`](http://docs.flutter.io/flutter/animation/Tween/evaluate.html) - the tween at the current value of an animation. This approach is most useful - for widgets that are already listening to the animation and hence - rebuilding whenever the animation changes value. - -2. You can [`animate`](http://docs.flutter.io/flutter/animation/Animatable/animate.html) - the tween based on the animation. Rather than returning a single value, the - animate function returns a new `Animation` that incorporates the tween. This - approach is most useful when you want to give the newly created animation to - another widget, which can then read the current value that incorporates - the tween as well as listen for changes to the value. - -# Architecture - -Animations are actually built from a number of core building blocks. +animation to determine the current state. + +Use these methods if you need to combine a tween with an animation to get a +concrete value: + ++ [`evaluate()`](http://docs.flutter.io/flutter/animation/Tween/evaluate.html): +Evaluates the tween at the current value of an animation. This approach is most +useful for widgets that are already listening to the animation and hence +rebuilding whenever the animation changes value. ++ [`animate()`](http://docs.flutter.io/flutter/animation/Animatable/animate.html) + Animates the tween based on the animation object's properties. Rather than +returning a single value, the animate function returns a new +[`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) +that incorporates the tween. This approach is most useful when you want to give +the newly created animation to another widget, which can then read the current +value that incorporates the tween as well as listen for changes to the value. -## Scheduler +### Scheduler The [`Scheduler`](http://docs.flutter.io/flutter/scheduler/Scheduler-class.html) @@ -140,7 +242,7 @@ callbacks have the same time, any animations triggered from these callbacks will appear to be exactly synchronised even if they take a few milliseconds to be executed. -## Tickers +### Tickers The [`Ticker`](http://docs.flutter.io/flutter/scheduler/Ticker-class.html) @@ -149,10 +251,9 @@ class hooks into the scheduler's mechanism to invoke a callback every tick. A `Ticker` can be started and stopped. When started, it returns a -`Future` that will resolve when it is stopped. - -Each tick, the `Ticker` provides the callback with the duration since -the first tick after it was started. +`Future` that will resolve when it is stopped. Each tick, the `Ticker` +provides the callback with the duration since the first tick after it was +started. Because tickers always give their elapsed time relative to the first tick after they were started, tickers are all synchronised. If you @@ -160,15 +261,13 @@ start three ticks at different times between two frames, they will all nonetheless be synchronised with the same starting time, and will subsequently tick in lockstep. -## Simulations +### Simulations The [`Simulation`](http://docs.flutter.io/newton/newton/Simulation-class.html) abstract class maps a relative time value (an elapsed time) to a -double value, and has a notion of completion. - -In principle simulations are stateless but in practice some -simulations (e.g. +double value, and has a notion of completion. In principle, simulations are +stateless but in practice some simulations (e.g. [`ScrollSimulation`](http://docs.flutter.io/newton/newton/ScrollSimulation-class.html)) change state irreversibly when queried. @@ -176,140 +275,50 @@ There are [various concrete implementations](http://docs.flutter.io/newton/newton/newton-library.html) of the `Simulation` class for different effects. -## Forces - The [`Force`](http://docs.flutter.io/flutter/animation/Force-class.html) abstract class provides a factory for `Simulation` instances. -## Animatables +### Animatables The [`Animatable`](http://docs.flutter.io/flutter/animation/Animatable-class.html) -abstract class maps a double to a value of a particular type. - -`Animatable` classes are stateless and immutable. - -### Tweens - -The +abstract class maps a double to a value of a particular type. `Animatable` +classes are stateless and immutable. The [`Tween`](http://docs.flutter.io/flutter/animation/Tween-class.html) -abstract class maps a double value nominally in the range 0.0-1.0 to a -typed value (e.g. a `Color`, or another double). It is an -`Animatable`. - -It has a notion of an output type (`T`), a `begin` value and an `end` -value of that type, and a way to interpolate (`lerp`) between the -begin and end values for a given input value (the double nominally in -the range 0.0-1.0). - -`Tween` classes are stateless and immutable. - -### Chaining animatables +abstract class is an `Animatable`. Passing an `Animatable` (the parent) to an `Animatable`'s `chain()` method creates a new `Animatable` subclass that applies the parent's mapping then the child's mapping. -## Curves - -The -[`Curve`](http://docs.flutter.io/flutter/animation/Curve-class.html) -abstract class maps doubles nominally in the range 0.0-1.0 to doubles -nominally in the range 0.0-1.0. - -`Curve` classes are stateless and immutable. - -## Animations - -The -[`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) -abstract class provides a value of a given type, a concept of -animation direction and animation status, and a listener interface to -register callbacks that get invoked when the value or status change. - -Some subclasses of `Animation` have values that never change -([`kAlwaysCompleteAnimation`](http://docs.flutter.io/flutter/animation/kAlwaysCompleteAnimation-constant.html), -[`kAlwaysDismissedAnimation`](http://docs.flutter.io/flutter/animation/kAlwaysDismissedAnimation-constant.html), -[`AlwaysStoppedAnimation`](http://docs.flutter.io/flutter/animation/AlwaysStoppedAnimation-class.html)); -registering callbacks on these has no effect as the callbacks are -never called. - -The `Animation` variant is special because it can be used to -represent a double nominally in the range 0.0-1.0, which is the input -expected by `Curve` and `Tween` classes, as well as some further -subclasses of `Animation`. +Passing an `Animation` (the new parent) to an `Animatable`'s +`animate()` method creates a new `Animation` subclass that acts like +the `Animatable` but is driven from the given parent. -Some `Animation` subclasses are stateless, merely forwarding listeners -to their parents. Some are very stateful. +## Chainable animations -### Chainable animations +Most [`Animation`](http://docs.flutter.io/flutter/animation/Animation-class.html) +subclasses take an explicit parent `Animation`. They are +driven by that parent. -Most `Animation` subclasses take an explicit "parent" -`Animation`. They are driven by that parent. +For example: -The `CurvedAnimation` subclass takes an `Animation` class (the -parent) and a couple of `Curve` classes (the forward and reverse ++ The [`CurvedAnimation`](http://docs.flutter.io/flutter/material/CurvedAnimation-class.html) +subclass takes an `Animation` class (the +parent) and some `Curve` classes (the forward and reverse curves) as input, and uses the value of the parent as input to the -curves to determine its output. `CurvedAnimation` is immutable and -stateless. +curves to determine its output. -The `ReverseAnimation` subclass takes an `Animation` class as -its parent and reverses all the values of the animation. It assumes -the parent is using a value nominally in the range 0.0-1.0 and returns -a value in the range 1.0-0.0. The status and direction of the parent -animation are also reversed. `CurvedAnimation` is immutable and -stateless. ++ The [`ReverseAnimation`](https://docs.flutter.io/flutter/widgets/ReverseAnimation-class.html) +subclass takes an `Animation` class as its parent and reverses all the +values of the animation. It assumes the parent is using a value nominally in +the range 0.0-1.0 and returns a value in the range 1.0-0.0. The status and +direction of the parent animation are also reversed. -The `ProxyAnimation` subclass takes an `Animation` class as -its parent and merely forwards the current state of that parent. -However, the parent is mutable. ++ The [`ProxyAnimation`](https://docs.flutter.io/flutter/animation/ProxyAnimation-class.html) +subclass takes an `Animation` class as its parent and merely forwards +the current state of that parent. However, the parent is mutable. -The `TrainHoppingAnimation` subclass takes two parents, and switches -between them when their values cross. - -### Animation Controllers - -The -[`AnimationController`](http://docs.flutter.io/flutter/animation/AnimationController-class.html) -is stateful `Animation` that uses a `Ticker` to give itself -life. It can be started and stopped. Each tick, it takes the time -elapsed since it was started and passes it to a `Simulation` to obtain -a value. That is then the value it reports. If the `Simulation` -reports that at that time it has ended, then the controller stops -itself. - -The animation controller can be given a lower and upper bound to -animate between, and a duration. - -In the simple case (using `forward()`, `reverse()`, `play()`, or -`resume()`), the animation controller simply does a linear -interpolation from the lower bound to the upper bound (or vice versa, -for the reverse direction) over the given duration. - -When using `repeat()`, the animation controller uses a linear -interpolation between the given bounds over the given duration, but -does not stop. - -When using `animateTo()`, the animation controller does a linear -interpolation over the given duration from the current value to the -given target. If no duration is given to the method, the default -duration of the controller and the range described by the controller's -lower bound and upper bound is used to determine the velocity of the -animation. - -When using `fling()`, a `Force` is used to create a specific -simulation which is then used to drive the controller. - -When using `animateWith()`, the given simulation is used to drive the -controller. - -These methods all return the future that the `Ticker` provides and -which will resolve when the controller next stops or changes -simulation. - -### Attaching animatables to animations - -Passing an `Animation` (the new parent) to an `Animatable`'s -`animate()` method creates a new `Animation` subclass that acts like -the `Animatable` but is driven from the given parent. ++ The [`TrainHoppingAnimation`](https://docs.flutter.io/flutter/animation/TrainHoppingAnimation-class.html) +subclass takes two parents, and switches between them when their values cross. \ No newline at end of file diff --git a/index.md b/index.md index 6d9653d91b6..375a3972951 100644 --- a/index.md +++ b/index.md @@ -41,6 +41,7 @@ Learn how to accomplish specific development tasks with Flutter. - [Accessing Platform and Third-Party Services](platform-services) - [Reading and Writing Files](reading-writing-files) - [Handling Text Input](text-input) + - [Animating Widgets](animating-widgets) ## Helpful Resources