diff --git a/animations/lib/src/basics/01_animated_container.dart b/animations/lib/src/basics/01_animated_container.dart index a2c7fda50..eb5b7df62 100644 --- a/animations/lib/src/basics/01_animated_container.dart +++ b/animations/lib/src/basics/01_animated_container.dart @@ -6,8 +6,6 @@ import 'dart:math'; import 'package:flutter/material.dart'; -const _duration = Duration(milliseconds: 400); - double generateBorderRadius() => Random().nextDouble() * 64; double generateMargin() => Random().nextDouble() * 64; Color generateColor() => Color(0xFFFFFFFF & Random().nextInt(0xFFFFFFFF)); @@ -39,13 +37,20 @@ class _AnimatedContainerDemoState extends State { } Widget build(BuildContext context) { + // This widget is built using an AnimatedContainer, one of the easiest to use + // animated Widgets. Whenever the AnimatedContainer's properties, such as decoration, + // change, it will handle animating from the previous value to the new value. You can + // specify both a Duration and a Curve for the animation. + // This Widget is useful for designing animated interfaces that just need to change + // the properties of a container. For example, you could use this to design expanding + // and shrinking cards. return Scaffold( appBar: AppBar(), body: Center( child: Column( children: [ Padding( - padding: const EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: SizedBox( width: 128, height: 128, @@ -55,7 +60,7 @@ class _AnimatedContainerDemoState extends State { color: color, borderRadius: BorderRadius.circular(borderRadius), ), - duration: _duration, + duration: Duration(milliseconds: 400), ), ), ), diff --git a/animations/lib/src/basics/03_animation_controller.dart b/animations/lib/src/basics/03_animation_controller.dart index c7c84c75a..bcae56de2 100644 --- a/animations/lib/src/basics/03_animation_controller.dart +++ b/animations/lib/src/basics/03_animation_controller.dart @@ -14,6 +14,11 @@ class AnimationControllerDemo extends StatefulWidget { class _AnimationControllerDemoState extends State with SingleTickerProviderStateMixin { + // Using the SingleTickerProviderStateMixin can ensure that our + // AnimationController only animates while the Widget is visible on the + // screen. This is a useful optimization that saves resources when the + // Widget is not visible. + static const Duration _duration = Duration(seconds: 1); AnimationController controller; @@ -22,20 +27,31 @@ class _AnimationControllerDemoState extends State super.initState(); controller = AnimationController(vsync: this, duration: _duration) + // The Widget's build needs to be called every time the animation's + // value changes. So add an listener here that will call setState() + // and trigger the build() method to be called by the framework. + // If your Widget's build is relatively simple, this is a good option. + // However, if your build method returns a tree of child Widgets and + // most of them are not animated you should consider using + // AnimatedBuilder instead. ..addListener(() { - // Force build() to be called again setState(() {}); }); } @override void dispose() { + // AnimationController is a stateful resource that needs to be disposed when + // this State gets disposed. controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { + // When building the widget you can read the AnimationController's value property + // when building child widgets. You can also check the status to see if the animation + // has completed. return Scaffold( appBar: AppBar(), body: Center( @@ -46,7 +62,8 @@ class _AnimationControllerDemoState extends State constraints: BoxConstraints(maxWidth: 200), child: Text( '${controller.value.toStringAsFixed(2)}', - style: Theme.of(context).textTheme.display3, + style: Theme.of(context).textTheme.display2, + textScaleFactor: 1 + controller.value, ), ), RaisedButton( diff --git a/animations/lib/src/basics/05_animated_builder.dart b/animations/lib/src/basics/05_animated_builder.dart index 90f92e1eb..29c185011 100644 --- a/animations/lib/src/basics/05_animated_builder.dart +++ b/animations/lib/src/basics/05_animated_builder.dart @@ -35,6 +35,10 @@ class _AnimatedBuilderDemoState extends State return Scaffold( appBar: AppBar(), body: Center( + // AnimatedBuilder handles listening to a given animation and calling the builder + // whenever the value of the animation change. This can be useful when a Widget + // tree contains some animated and non-animated elements, as only the subtree + // created by the builder needs to be re-built when the animation changes. child: AnimatedBuilder( animation: animation, builder: (context, child) { @@ -50,6 +54,10 @@ class _AnimatedBuilderDemoState extends State }, ); }, + // AnimatedBuilder can also accept a pre-built child Widget which is useful + // if there is a non-animated Widget contained within the animated widget. + // This can improve performance since this widget doesn't need to be rebuilt + // when the animation changes. child: Text( 'Change Color', style: TextStyle(color: Colors.white),