Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter Animations First Step

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for konifar konifar
September 01, 2018

Flutter Animations First Step

GDG Tokyo 2018で話した、Flutterでアニメーションを実装する方法です。
https://gdg-tokyo.connpass.com/event/95307/

Avatar for konifar

konifar

September 01, 2018
Tweet

More Decks by konifar

Other Decks in Programming

Transcript

  1. Basic classes - AnimationController - ࣌ؒΛܾΊɺ։࢝ɾऴྃͳͲͷ੍ޚΛ͢Δ - Tween - มߋ͢Δ஋ͷൣғΛܾΊΔ

    - CurvedAnimation - ஋ͷมԽʹ؇ٸΛ͚ͭΔ - AnimatedBuilder - มԽͨ͠஋Λඳը͢Δ
  2. Basic classes - AnimationController - 2000ms ͷ࣌ؒͰϦϐʔτ - Tween -

    0~300 ͷ஋ - CurvedAnimation - Linearʢ౳଎ʣ - AnimatedBuilder - 1ඵؒʹ60ճ˘Λඳը
  3. Basic classes - AnimationController - 2000ms ͷ࣌ؒͰϦϐʔτ - Tween -

    0~300 ͷ஋ - CurvedAnimation - Linearʢ౳଎ʣ - AnimatedBuilder - 1ඵؒʹ60ճ˘Λඳը Required Optional
  4. class BasicAnimationApp extends StatefulWidget { @override _BasicAnimationAppState createState() => new

    _BasicAnimationAppState(); } class _BasicAnimationAppState extends State<BasicAnimationApp> { @override Widget build(BuildContext context) { return Center( child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.blue[400], ), ), ); } } void main() { runApp(BasicAnimationApp()); } Ξχϝʔγϣϯͳ͠
  5. class BasicAnimationApp extends StatefulWidget { @override _BasicAnimationAppState createState() => new

    _BasicAnimationAppState(); } class _BasicAnimationAppState extends State<BasicAnimationApp> { @override Widget build(BuildContext context) { return Center( child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.blue[400], ), ), ); } } void main() { runApp(BasicAnimationApp()); } Ξχϝʔγϣϯͳ͠ buildϝιουͷதͷ width, height ͕ 300ݻఆͳͷͰɺͨͩͷ੨͍˘͕දࣔ͞ΕΔ͚ͩɻ
  6. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } …
  7. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … initState()ͷதͰɺ2000msͰಈ࡞͢Δ AnimationControllerΠϯελϯεΛੜ੒ɻ
  8. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … Ξχϝʔγϣϯ࣌ͷແବͳඳըΛ๷͙ͨΊʹ ର৅ͷStateʹTickerProviderΛ࣮૷ͯ͠౉͢ɻ
  9. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … initState()ͷதͰΞχϝʔγϣϯͷ։࢝ɻ දࣔͨ͠Β͙͢ʹಈ͖ग़͢ɻ
  10. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … buildϝιουͷதͰɺcontroller.valueͷ஋Λ ࢖ͬͯWidgetπϦʔΛ࡞Δɻ controller.value͸0.0~1.0ͳͷͰɺ 300ഒͯ͠widthͱheightʹηοτ͢Δɻ
  11. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … AnimationController͕஋Λੜ੒ ͢Δͨͼʹඳը͢ΔͨΊʹɺ ListenerΛηοτͯ͠setState() ΛݺͿɻ
  12. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; ..

    @override dispose() { controller.dispose(); super.dispose(); } } dispose() Λ๨Εͣʹ dispose() ΛݺΜͰ͓͔ͳ͍ͱ ϝϞϦϦʔΫ͢ΔͷͰ஫ҙɻ
  13. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; @override

    initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) ..addListener(() { setState(() { }); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); } }); controller.forward(); } Ξχϝʔγϣϯ͕ऴΘͬͨΒ൓ରํ޲ʢreverseʣʹ ಈ͔ͯ͠ɺऴΘͬͨΒ·ͨ։࢝ʢforwardʣ͢Δɻ
  14. import 'package:flutter/scheduler.dart';
 
 class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin {

    AnimationController controller; .. @override Widget build(BuildContext context) {
 timeDilation = 2.0; return Center( child: Container( width: controller.value * 300.0, height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } .. scheduler.dartΛimport͠ timeDilationʹ஋Ληοτ͢Δɻ
  15. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), // width: controller.value * 300.0, // height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } …
  16. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), // width: controller.value * 300.0, // height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … 0.0 ~ 300.0 Ͱ஋ΛมԽͤ͞ΔͨΊͷ doubleܕͷTweenΠϯελϯεΛੜ੒ɻ
  17. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), // width: controller.value * 300.0, // height: controller.value * 300.0, decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … buildϝιουͰWidgetΛ૊ΈཱͯΔࡍʹ Tween͔Β0.0 ~ 300.0ͷ஋Λड͚औΕΔɻ
  18. ͞·͟·ͳ Tween - ColorTween - SizeTween - RectTween - BorderRadiusTween

    - DecorationTween - BoxConstraintsTween - https://docs.flutter.io/flutter/animation/Tween-class.html
  19. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); final _colorTween = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), decoration: BoxDecoration(color: Colors.blue[400]), // decoration: BoxDecoration(color: Colors.blue[400]), ), ); } …
  20. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); final _colorTween = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), decoration: BoxDecoration(color: Colors.blue[400]), // decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … beginʹ੨ɺendʹԫ৭Λ౉ͯ͠ ColorTween ΠϯελϯεΛੜ੒ɻ
  21. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller;
 final

    _sizeTween = Tween<double>(begin: 0.0, end: 300.0); final _colorTween = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); @override initState() { super.initState(); controller = AnimationController( .. controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(controller), height: _sizeTween.evaluate(controller), decoration: BoxDecoration(color: _colorTween.evaluate(controller)), // decoration: BoxDecoration(color: Colors.blue[400]), ), ); } … buildϝιουͷதͰɺ ColorTween ͔Β Color ΛऔΓग़ͯ͠ηοτɻ
  22. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation

    animation; .. @override initState() { super.initState(); controller = AnimationController( .. animation = CurvedAnimation(parent: controller, curve: Curves.ease); controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(animation), height: _sizeTween.evaluate(animation), decoration: BoxDecoration(color: _colorTween.evaluate(animation)), ), ); } ..
  23. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation

    animation; .. @override initState() { super.initState(); controller = AnimationController( .. animation = CurvedAnimation(parent: controller, curve: Curves.ease); controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(animation), height: _sizeTween.evaluate(animation), decoration: BoxDecoration(color: _colorTween.evaluate(animation)), ), ); } .. initState()ͷதͰɺCurvedAnimationΛੜ੒ɻ ୈೋҾ਺ͰCurveΛࢦఆ͢Δɻ
  24. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation

    animation; .. @override initState() { super.initState(); controller = AnimationController( .. animation = CurvedAnimation(parent: controller, curve: Curves.ease); controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(animation), height: _sizeTween.evaluate(animation), decoration: BoxDecoration(color: _colorTween.evaluate(animation)), ), ); } .. buildϝιουͷதͰTween͔Β஋ΛऔΓग़͢ࡍʹ controllerͷ୅ΘΓʹanimationΛࢦఆ͢Δɻ
  25. Curves - bounceIn/bounceInOut/bounceOut - Decelerate - ease/easeIn/easeInOut/easeOut - elasticIn/elasticInOut/elasticOut -

    FastOutSlowIn - Linear - https://docs.flutter.io/flutter/animation/Curves-class.html
  26. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation

    animation; final _sizeTween = Tween<double>(begin: 0.0, end: 300.0); final _colorTween = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); .. @override initState() { super.initState(); controller = AnimationController( .. animation = CurvedAnimation(parent: controller, curve: Curves.ease); controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(animation), height: _sizeTween.evaluate(animation), decoration: BoxDecoration(color: _colorTween.evaluate(animation)), ), ); } ..
  27. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation

    animation; final _sizeTween = Tween<double>(begin: 0.0, end: 300.0); final _colorTween = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); .. @override initState() { super.initState(); controller = AnimationController( .. animation = CurvedAnimation(parent: controller, curve: Curves.ease); controller.forward(); } @override Widget build(BuildContext context) { return Center( child: Container( width: _sizeTween.evaluate(animation), height: _sizeTween.evaluate(animation), decoration: BoxDecoration(color: _colorTween.evaluate(animation)), ), ); } .. ͜ͷ͋ͨΓΛ1ͭͷWidgetʹ·ͱΊΕ͹ ݟ௨͠΋Α͘ͳΔ͠࠶ར༻΋ՄೳʹͳΔɻ
  28. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), super(key: key); final Animation<double> controller; final Animation<double> sizeAnimation; final Animation<Color> colorAnimation; @override Widget build(BuildContext context) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } }
  29. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), super(key: key); final Animation<double> controller; final Animation<double> sizeAnimation; final Animation<Color> colorAnimation; @override Widget build(BuildContext context) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } } Ҿ਺ʹAnimationControllerΛ࣋ͭ StatelessWidgetɻ
  30. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), super(key: key); final Animation<double> controller; final Animation<double> sizeAnimation; final Animation<Color> colorAnimation; @override Widget build(BuildContext context) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } } TweenͱCurvedAnimationΛ࢖ͬͯ sizeAnimationͱcolorAnimationΛ ίϯετϥΫλͰੜ੒͓ͯ͘͠ɻ
  31. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]).animate( CurvedAnimation(parent: controller, curve: Curves.ease), ), super(key: key); final Animation<double> controller; final Animation<double> sizeAnimation; final Animation<Color> colorAnimation; @override Widget build(BuildContext context) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } } buildϝιουͷதͰ sizeAnimationͱColorAnimationͷ ஋Λ࢖ͬͯWidgetπϦʔΛߏஙɻ
  32. AnimationController controller; // Animation animation; // final _sizeTween = Tween<double>(begin:

    0.0, end: 300.0); // final _colorTween = // ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]); @override initState() { super.initState(); controller = AnimationController( .. // animation = CurvedAnimation(parent: controller, curve: Curves.ease); // _sizeTween.animate(animation); // _colorTween.animate(animation); controller.forward(); } @override Widget build(BuildContext context) { // timeDilation = 2.0; // return Center( // child: Container( // width: _sizeTween.evaluate(animation), // height: _sizeTween.evaluate(animation), // decoration: BoxDecoration(color: _colorTween.evaluate(animation)), // ), // ); return SampleAnimation(controller: controller); } ݺͼग़͠ଆ͸controller੍͚ͩޚ͢Ε͹Α͍ɻ
  33. @override initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds:

    2000), vsync: this) ..addListener(() { setState(() {}); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); } }); controller.forward(); }
  34. @override initState() { super.initState(); controller = AnimationController( duration: const Duration(milliseconds:

    2000), vsync: this) ..addListener(() { setState(() {}); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); } }); controller.forward(); } ࠶ඳը͢ΔͨΊʹListenerΛηοτͯ͠ setState()ΛݺͿ৑௕ͳίʔυɻ => AnimatedBuilderΛ࢖ͬͯলུՄೳɻ
  35. class SampleAnimation extends StatelessWidget { .. Widget _buildAnimation(BuildContext context, Widget

    child) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: controller, ); } }
  36. class SampleAnimation extends StatelessWidget { .. Widget _buildAnimation(BuildContext context, Widget

    child) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: controller, ); } } buildϝιουͷதͰ AnimatedBuilderΛฦ͢ɻ
  37. class SampleAnimation extends StatelessWidget { .. Widget _buildAnimation(BuildContext context, Widget

    child) { return Center( child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration(color: colorAnimation.value), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: controller, ); } } builderʹ͸WidgetΛੜ੒͢Δؔ਺Λ౉͢ɻ
  38. class _BasicAnimationAppState extends State<BasicAnimationApp> with SingleTickerProviderStateMixin { .. @override initState()

    { super.initState(); controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this) // ..addListener(() { // setState(() {}); // }) .. } ݺͼग़͠ݩͰ͸ addListenerͱsetState͕ෆཁʹɻ
  39. AnimatedWidget ͱ AnimatedBuilder ͷ࢖͍෼͚ /// A general-purpose widget for building

    animations. /// /// 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. /// /// For simple cases without additional state, consider using /// [AnimatedWidget]. /// /// ## Performance optimizations /// /// If your [builder] function contains a subtree that does not depend on the /// animation, it's more efficient to build that subtree once instead of /// rebuilding it on every animation tick. /// /// If you pass the pre-built subtree as the [child] parameter, the /// AnimatedBuilder will pass it back to your builder function so that you /// can incorporate it into your build. /// /// Using this pre-built child is entirely optional, but can improve /// performance significantly in some cases and is therefore a good practice.
  40. AnimatedWidget ͱ AnimatedBuilder ͷ࢖͍෼͚ /// A general-purpose widget for building

    animations. /// /// 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. /// /// For simple cases without additional state, consider using /// [AnimatedWidget]. /// /// ## Performance optimizations /// /// If your [builder] function contains a subtree that does not depend on the /// animation, it's more efficient to build that subtree once instead of /// rebuilding it on every animation tick. /// /// If you pass the pre-built subtree as the [child] parameter, the /// AnimatedBuilder will pass it back to your builder function so that you /// can incorporate it into your build. /// /// Using this pre-built child is entirely optional, but can improve /// performance significantly in some cases and is therefore a good practice. builderͷඞཁͷͳ͍γϯϓϧͳWidgetͷ ৔߹ʹ͸ɺAnimatedWidgetΛ࢖͏ͷ͕Α͍ɻ Ξχϝʔγϣϯ͠ͳ͍WidgetΛؚΉ৔߹ʹ͸ɺ AnimatedBuilderΛ࢖͏ํ͕ແବͳ࠶ඳըΛ͠ ͳ͍ͷͰύϑΥʔϚϯε͕Α͍ɻ
  41. AnimatedWidget - RelativePositionedTransition - SlideTransition - SizeTransition - ScaleTransition -

    DecoratedBoxTransition - RotationTransition - PositionedTransition - AlignTransition
  42. AnimatedBuilder - BottomSheet - ExpansionTile - PopupMenu - ProgressIndicator -

    RefreshIndicator - Scaffold - SnackBar - TabBar - TextField
  43. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.5, curve: Curves.ease), // curve: Curves.ease, ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.5, 0.9, curve: Curves.ease), // curve: Curves.ease, ), ), super(key: key);
  44. class SampleAnimation extends StatelessWidget { SampleAnimation({Key key, this.controller}) : sizeAnimation

    = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve: Interval(0.0, 0.5, curve: Curves.ease), // curve: Curves.ease, ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.5, 0.9, curve: Curves.ease), // curve: Curves.ease, ), ), super(key: key); 0 ~ 1000msͷؒͰΞχϝʔγϣϯ 1000 ~ 1800msͷؒͰΞχϝʔγϣϯ
  45. sizeAnimation = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve:

    Interval(0.0, 0.3, curve: Curves.ease), ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.3, 0.7, curve: Curves.ease), ), ), rotateAnimation = Tween<double>(begin: 0.0, end: 0.75).animate( CurvedAnimation( parent: controller, curve: Interval(0.4, 0.7, curve: Curves.ease), ), ), borderRadiusAnimation = BorderRadiusTween( begin: BorderRadius.circular(0.0), end: BorderRadius.circular(150.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.7, 0.9, curve: Curves.ease), ), ),
  46. sizeAnimation = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve:

    Interval(0.0, 0.3, curve: Curves.ease), ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.3, 0.7, curve: Curves.ease), ), ), rotateAnimation = Tween<double>(begin: 0.0, end: 0.75).animate( CurvedAnimation( parent: controller, curve: Interval(0.4, 0.7, curve: Curves.ease), ), ), borderRadiusAnimation = BorderRadiusTween( begin: BorderRadius.circular(0.0), end: BorderRadius.circular(150.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.7, 0.9, curve: Curves.ease), ), ), sizeAnimation : 0 ~ 0.6ඵͰେ͖͘ͳΔɻ
  47. sizeAnimation = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve:

    Interval(0.0, 0.3, curve: Curves.ease), ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.3, 0.7, curve: Curves.ease), ), ), rotateAnimation = Tween<double>(begin: 0.0, end: 0.75).animate( CurvedAnimation( parent: controller, curve: Interval(0.4, 0.7, curve: Curves.ease), ), ), borderRadiusAnimation = BorderRadiusTween( begin: BorderRadius.circular(0.0), end: BorderRadius.circular(150.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.7, 0.9, curve: Curves.ease), ), ), colorAnimation : 0.6 ~ 1.4ඵͰ৭Λม͑Δɻ rotateAnimation : 0.8 ~ 1.4ඵͰ270౓ճస͢Δɻ
  48. sizeAnimation = Tween<double>(begin: 0.0, end: 300.0).animate( CurvedAnimation( parent: controller, curve:

    Interval(0.0, 0.3, curve: Curves.ease), ), ), colorAnimation = ColorTween(begin: Colors.blue[400], end: Colors.yellow[400]) .animate( CurvedAnimation( parent: controller, curve: Interval(0.3, 0.7, curve: Curves.ease), ), ), rotateAnimation = Tween<double>(begin: 0.0, end: 0.75).animate( CurvedAnimation( parent: controller, curve: Interval(0.4, 0.7, curve: Curves.ease), ), ), borderRadiusAnimation = BorderRadiusTween( begin: BorderRadius.circular(0.0), end: BorderRadius.circular(150.0), ).animate( CurvedAnimation( parent: controller, curve: Interval(0.7, 0.9, curve: Curves.ease), ), ), borderRadiusAnimation : 1.4 ~ 1.8ඵͰ˘Λ˓ʹมԽͤ͞Δɻ
  49. Widget _buildAnimation(BuildContext context, Widget child) { return Center( child: Transform(

    transform: Matrix4.rotationZ(rotateAnimation.value * math.pi * 2.0), alignment: Alignment.center, child: Container( width: sizeAnimation.value, height: sizeAnimation.value, decoration: BoxDecoration( color: colorAnimation.value, borderRadius: borderRadiusAnimation.value), ), ), ); } ֤animationͷ஋Λ࢖ͬͯWidgetπϦʔΛߏஙɻ