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

Flutter Animations First Step

konifar
September 01, 2018

Flutter Animations First Step

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

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πϦʔΛߏஙɻ