diff --git a/examples/animation/.gitignore b/examples/animation/.gitignore new file mode 100644 index 0000000000..a596482f79 --- /dev/null +++ b/examples/animation/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +pubspec.lock + +*/**/android +*/**/ios +*/**/.gitignore +*/**/.metadata diff --git a/examples/animation/animate0/README.md b/examples/animation/animate0/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate0/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/examples/animation/animate0/lib/main.dart b/examples/animation/animate0/lib/main.dart new file mode 100644 index 0000000000..6a493fc733 --- /dev/null +++ b/examples/animation/animate0/lib/main.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +void main() => runApp(LogoApp()); + +class LogoApp extends StatefulWidget { + _LogoAppState createState() => _LogoAppState(); +} + +class _LogoAppState extends State { + @override + Widget build(BuildContext context) { + return Center( + child: Container( + margin: EdgeInsets.symmetric(vertical: 10), + height: 300, + width: 300, + child: FlutterLogo(), + ), + ); + } +} diff --git a/examples/animation/animate0/pubspec.yaml b/examples/animation/animate0/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate0/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate0/test/widget_test.dart b/examples/animation/animate0/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate0/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/examples/animation/animate1/README.md b/examples/animation/animate1/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate1/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/src/_includes/code/animation/animate1/main.dart b/examples/animation/animate1/lib/main.dart similarity index 56% rename from src/_includes/code/animation/animate1/main.dart rename to examples/animation/animate1/lib/main.dart index 109639bc35..6052163153 100644 --- a/src/_includes/code/animation/animate1/main.dart +++ b/examples/animation/animate1/lib/main.dart @@ -1,10 +1,8 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; +void main() => runApp(LogoApp()); + class LogoApp extends StatefulWidget { _LogoAppState createState() => _LogoAppState(); } @@ -13,23 +11,29 @@ class _LogoAppState extends State with SingleTickerProviderStateMixin { Animation animation; AnimationController controller; - initState() { + @override + void initState() { super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); - animation = Tween(begin: 0.0, end: 300.0).animate(controller) + controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); + // #docregion addListener + animation = Tween(begin: 0, end: 300).animate(controller) ..addListener(() { + // #enddocregion addListener setState(() { - // the state that has changed here is the animation object’s value + // The state that has changed here is the animation object’s value. }); + // #docregion addListener }); + // #enddocregion addListener controller.forward(); } + @override Widget build(BuildContext context) { return Center( child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), + margin: EdgeInsets.symmetric(vertical: 10), height: animation.value, width: animation.value, child: FlutterLogo(), @@ -37,12 +41,9 @@ class _LogoAppState extends State with SingleTickerProviderStateMixin { ); } - dispose() { + @override + void dispose() { controller.dispose(); super.dispose(); } } - -void main() { - runApp(LogoApp()); -} diff --git a/examples/animation/animate1/pubspec.yaml b/examples/animation/animate1/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate1/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate1/test/widget_test.dart b/examples/animation/animate1/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate1/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/examples/animation/animate2/README.md b/examples/animation/animate2/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate2/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/src/_includes/code/animation/animate2/main.dart b/examples/animation/animate2/lib/main.dart similarity index 57% rename from src/_includes/code/animation/animate2/main.dart rename to examples/animation/animate2/lib/main.dart index b5098bd5a6..6f725d6790 100644 --- a/src/_includes/code/animation/animate2/main.dart +++ b/examples/animation/animate2/lib/main.dart @@ -1,12 +1,9 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Demonstrates a simple animation with AnimatedWidget. - import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; +void main() => runApp(LogoApp()); + +// #docregion AnimatedLogo class AnimatedLogo extends AnimatedWidget { AnimatedLogo({Key key, Animation animation}) : super(key: key, listenable: animation); @@ -15,7 +12,7 @@ class AnimatedLogo extends AnimatedWidget { final Animation animation = listenable; return Center( child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), + margin: EdgeInsets.symmetric(vertical: 10), height: animation.value, width: animation.value, child: FlutterLogo(), @@ -23,33 +20,31 @@ class AnimatedLogo extends AnimatedWidget { ); } } +// #enddocregion AnimatedLogo class LogoApp extends StatefulWidget { _LogoAppState createState() => _LogoAppState(); } class _LogoAppState extends State with SingleTickerProviderStateMixin { - AnimationController controller; Animation animation; + AnimationController controller; - initState() { + @override + void initState() { super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); - animation = Tween(begin: 0.0, end: 300.0).animate(controller); + controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); + animation = Tween(begin: 0, end: 300).animate(controller); controller.forward(); } - Widget build(BuildContext context) { - return AnimatedLogo(animation: animation); - } + @override + Widget build(BuildContext context) => AnimatedLogo(animation: animation); - dispose() { + @override + void dispose() { controller.dispose(); super.dispose(); } } - -void main() { - runApp(LogoApp()); -} diff --git a/examples/animation/animate2/pubspec.yaml b/examples/animation/animate2/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate2/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate2/test/widget_test.dart b/examples/animation/animate2/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate2/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/examples/animation/animate3/README.md b/examples/animation/animate3/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate3/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/examples/animation/animate3/lib/main.dart b/examples/animation/animate3/lib/main.dart new file mode 100644 index 0000000000..7c2047d95a --- /dev/null +++ b/examples/animation/animate3/lib/main.dart @@ -0,0 +1,61 @@ +import 'package:flutter/animation.dart'; +import 'package:flutter/material.dart'; + +void main() => runApp(LogoApp()); + +class AnimatedLogo extends AnimatedWidget { + AnimatedLogo({Key key, Animation animation}) + : super(key: key, listenable: animation); + + Widget build(BuildContext context) { + final Animation animation = listenable; + return Center( + child: Container( + margin: EdgeInsets.symmetric(vertical: 10), + height: animation.value, + width: animation.value, + child: FlutterLogo(), + ), + ); + } +} + +class LogoApp extends StatefulWidget { + _LogoAppState createState() => _LogoAppState(); +} + +// #docregion print-state +class _LogoAppState extends State with SingleTickerProviderStateMixin { + Animation animation; + AnimationController controller; + + @override + void initState() { + super.initState(); + controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); + animation = Tween(begin: 0, end: 300).animate(controller) + // #enddocregion print-state + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + controller.reverse(); + } else if (status == AnimationStatus.dismissed) { + controller.forward(); + } + }) + // #docregion print-state + ..addStatusListener((state) => print('$state')); + controller.forward(); + } + // #enddocregion print-state + + @override + Widget build(BuildContext context) => AnimatedLogo(animation: animation); + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + // #docregion print-state +} diff --git a/examples/animation/animate3/pubspec.yaml b/examples/animation/animate3/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate3/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate3/test/widget_test.dart b/examples/animation/animate3/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate3/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/examples/animation/animate4/README.md b/examples/animation/animate4/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate4/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/examples/animation/animate4/lib/main.dart b/examples/animation/animate4/lib/main.dart new file mode 100644 index 0000000000..b0860c00b0 --- /dev/null +++ b/examples/animation/animate4/lib/main.dart @@ -0,0 +1,67 @@ +import 'package:flutter/animation.dart'; +import 'package:flutter/material.dart'; + +void main() => runApp(LogoApp()); + +// #docregion LogoWidget +class LogoWidget extends StatelessWidget { + // Leave out the height and width so it fills the animating parent + Widget build(BuildContext context) => Container( + margin: EdgeInsets.symmetric(vertical: 10), + child: FlutterLogo(), + ); +} +// #enddocregion LogoWidget + +// #docregion GrowTransition +class GrowTransition extends StatelessWidget { + GrowTransition({this.child, this.animation}); + + final Widget child; + final Animation animation; + + Widget build(BuildContext context) => Center( + child: AnimatedBuilder( + animation: animation, + builder: (context, child) => Container( + height: animation.value, + width: animation.value, + child: child, + ), + child: child), + ); +} +// #enddocregion GrowTransition + +class LogoApp extends StatefulWidget { + _LogoAppState createState() => _LogoAppState(); +} + +// #docregion print-state +class _LogoAppState extends State with SingleTickerProviderStateMixin { + Animation animation; + AnimationController controller; + + @override + void initState() { + super.initState(); + controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); + animation = Tween(begin: 0, end: 300).animate(controller); + controller.forward(); + } + // #enddocregion print-state + + @override + Widget build(BuildContext context) => GrowTransition( + child: LogoWidget(), + animation: animation, + ); + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + // #docregion print-state +} diff --git a/examples/animation/animate4/pubspec.yaml b/examples/animation/animate4/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate4/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate4/test/widget_test.dart b/examples/animation/animate4/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate4/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/examples/animation/animate5/README.md b/examples/animation/animate5/README.md new file mode 120000 index 0000000000..fe84005413 --- /dev/null +++ b/examples/animation/animate5/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/examples/animation/animate5/lib/main.dart b/examples/animation/animate5/lib/main.dart new file mode 100644 index 0000000000..1e5f4ef4a2 --- /dev/null +++ b/examples/animation/animate5/lib/main.dart @@ -0,0 +1,122 @@ +// #docregion ShakeCurve +import 'dart:math'; + +// #enddocregion ShakeCurve +import 'package:flutter/animation.dart'; +import 'package:flutter/material.dart'; + +void main() => runApp(LogoApp()); + +// #docregion diff +class AnimatedLogo extends AnimatedWidget { + // Make the Tweens static because they don't change. + static final _opacityTween = Tween(begin: 0.1, end: 1); + static final _sizeTween = Tween(begin: 0, end: 300); + + AnimatedLogo({Key key, Animation animation}) + : super(key: key, listenable: animation); + + Widget build(BuildContext context) { + final Animation animation = listenable; + return Center( + child: Opacity( + opacity: _opacityTween.evaluate(animation), + child: Container( + margin: EdgeInsets.symmetric(vertical: 10), + height: _sizeTween.evaluate(animation), + width: _sizeTween.evaluate(animation), + child: FlutterLogo(), + ), + ), + ); + } +} + +class LogoApp extends StatefulWidget { + _LogoAppState createState() => _LogoAppState(); +} + +class _LogoAppState extends State with SingleTickerProviderStateMixin { + Animation animation; + AnimationController controller; + + @override + void initState() { + super.initState(); + // #docregion AnimationController, tweens + controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); + // #enddocregion AnimationController, tweens + animation = CurvedAnimation(parent: controller, curve: Curves.easeIn) + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + controller.reverse(); + } else if (status == AnimationStatus.dismissed) { + controller.forward(); + } + }); + controller.forward(); + } + + @override + Widget build(BuildContext context) => AnimatedLogo(animation: animation); + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } +} +// #enddocregion diff + +// Extra code used only in the tutorial explanations. It is not used by the app. + +class UsedInTutorialTextOnly extends _LogoAppState { + UsedInTutorialTextOnly() { + // ignore: unused_local_variable + var animation, sizeAnimation, opacityAnimation, tween, colorTween; + + // #docregion CurvedAnimation + animation = CurvedAnimation(parent: controller, curve: Curves.easeIn); + // #enddocregion CurvedAnimation + + // #docregion tweens + sizeAnimation = Tween(begin: 0, end: 300).animate(controller); + opacityAnimation = Tween(begin: 0.1, end: 1).animate(controller); + // #enddocregion tweens + + // #docregion tween + tween = Tween(begin: -200, end: 0); + // #enddocregion tween + + // #docregion colorTween + colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54); + // #enddocregion colorTween + } + + usedInTutorialOnly1() { + // #docregion IntTween + AnimationController controller = AnimationController( + duration: const Duration(milliseconds: 500), vsync: this); + Animation alpha = IntTween(begin: 0, end: 255).animate(controller); + // #enddocregion IntTween + return alpha; + } + + usedInTutorialOnly2() { + // #docregion IntTween-curve + AnimationController controller = AnimationController( + duration: const Duration(milliseconds: 500), vsync: this); + final Animation curve = + CurvedAnimation(parent: controller, curve: Curves.easeOut); + Animation alpha = IntTween(begin: 0, end: 255).animate(curve); + // #enddocregion IntTween-curve + return alpha; + } +} + +// #docregion ShakeCurve +class ShakeCurve extends Curve { + @override + double transform(double t) => sin(t * pi * 2); +} diff --git a/examples/animation/animate5/pubspec.yaml b/examples/animation/animate5/pubspec.yaml new file mode 100644 index 0000000000..003a1b5770 --- /dev/null +++ b/examples/animation/animate5/pubspec.yaml @@ -0,0 +1,19 @@ +name: animation +description: > + Sample app from "Building Layouts", https://flutter.io/docs/development/ui/layout. +version: 1.0.0 + +environment: + sdk: '>=2.0.0-dev.68.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/examples/animation/animate5/test/widget_test.dart b/examples/animation/animate5/test/widget_test.dart new file mode 100644 index 0000000000..4d18e686d3 --- /dev/null +++ b/examples/animation/animate5/test/widget_test.dart @@ -0,0 +1,12 @@ +// Basic Flutter widget test. Learn more at https://flutter.io/docs/testing. + +import 'package:animation/main.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter/material.dart'; + +void main() { + testWidgets('Codelab smoke test', (WidgetTester tester) async { + await tester.pumpWidget(new LogoApp()); + expect(find.byType(FlutterLogo), findsOneWidget); + }); +} diff --git a/src/_includes/code/animation/animate1/pubspec.yaml b/src/_includes/code/animation/animate1/pubspec.yaml deleted file mode 100644 index de1bd3b2da..0000000000 --- a/src/_includes/code/animation/animate1/pubspec.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: animate1 -description: A new Flutter project. - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/. - - # To add assets from package dependencies, first ensure the asset - # is in the lib/ directory of the dependency. Then, - # refer to the asset with a path prefixed with - # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not - # include `lib/` in the asset path. - # - # Here is an example: - # - # assets: - # - packages/PACKAGE_NAME/path/to/asset - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 diff --git a/src/_includes/code/animation/animate2/pubspec.yaml b/src/_includes/code/animation/animate2/pubspec.yaml deleted file mode 100644 index 6aeff9cad0..0000000000 --- a/src/_includes/code/animation/animate2/pubspec.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: animate2 -description: A new Flutter project. - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/. - - # To add assets from package dependencies, first ensure the asset - # is in the lib/ directory of the dependency. Then, - # refer to the asset with a path prefixed with - # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not - # include `lib/` in the asset path. - # - # Here is an example: - # - # assets: - # - packages/PACKAGE_NAME/path/to/asset - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 diff --git a/src/_includes/code/animation/animate3/main.dart b/src/_includes/code/animation/animate3/main.dart deleted file mode 100644 index 2cfeea351b..0000000000 --- a/src/_includes/code/animation/animate3/main.dart +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Demonstrates a repeating animation. - -import 'package:flutter/animation.dart'; -import 'package:flutter/material.dart'; - -class AnimatedLogo extends AnimatedWidget { - AnimatedLogo({Key key, Animation animation}) - : super(key: key, listenable: animation); - - Widget build(BuildContext context) { - final Animation animation = listenable; - return Center( - child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), - height: animation.value, - width: animation.value, - child: FlutterLogo(), - ), - ); - } -} - -class LogoApp extends StatefulWidget { - _LogoAppState createState() => _LogoAppState(); -} - -class _LogoAppState extends State with SingleTickerProviderStateMixin { - AnimationController controller; - Animation animation; - - initState() { - super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); - animation = Tween(begin: 0.0, end: 300.0).animate(controller); - - animation.addStatusListener((status) { - if (status == AnimationStatus.completed) { - controller.reverse(); - } else if (status == AnimationStatus.dismissed) { - controller.forward(); - } - }); - controller.forward(); - } - - Widget build(BuildContext context) { - return AnimatedLogo(animation: animation); - } - - dispose() { - controller.dispose(); - super.dispose(); - } -} - -void main() { - runApp(LogoApp()); -} diff --git a/src/_includes/code/animation/animate3/pubspec.yaml b/src/_includes/code/animation/animate3/pubspec.yaml deleted file mode 100644 index fccd2e9722..0000000000 --- a/src/_includes/code/animation/animate3/pubspec.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: animate3 -description: A new Flutter project. - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/. - - # To add assets from package dependencies, first ensure the asset - # is in the lib/ directory of the dependency. Then, - # refer to the asset with a path prefixed with - # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not - # include `lib/` in the asset path. - # - # Here is an example: - # - # assets: - # - packages/PACKAGE_NAME/path/to/asset - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 diff --git a/src/_includes/code/animation/animate4/main.dart b/src/_includes/code/animation/animate4/main.dart deleted file mode 100644 index d84bd58fe4..0000000000 --- a/src/_includes/code/animation/animate4/main.dart +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Demonstrate a factored animation with AnimatedBuilder. - -import 'package:flutter/animation.dart'; -import 'package:flutter/material.dart'; - -class LogoWidget extends StatelessWidget { - // Leave out the height and width so it fills the animating parent - build(BuildContext context) { - return Container( - margin: EdgeInsets.symmetric(vertical: 10.0), - child: FlutterLogo()); - } -} - -class GrowTransition extends StatelessWidget { - GrowTransition({this.child, this.animation}); - - final Widget child; - final Animation animation; - - Widget build(BuildContext context) { - return Center( - child: AnimatedBuilder( - animation: animation, - builder: (BuildContext context, Widget child) { - return Container( - height: animation.value, width: animation.value, child: child); - }, - child: child), - ); - } -} - -class LogoApp extends StatefulWidget { - _LogoAppState createState() => _LogoAppState(); -} - -class _LogoAppState extends State with SingleTickerProviderStateMixin { - Animation animation; - AnimationController controller; - - initState() { - super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); - final CurvedAnimation curve = - CurvedAnimation(parent: controller, curve: Curves.easeIn); - animation = Tween(begin: 0.0, end: 300.0).animate(curve); - controller.forward(); - } - - Widget build(BuildContext context) { - return GrowTransition(child: LogoWidget(), animation: animation); - } - - dispose() { - controller.dispose(); - super.dispose(); - } -} - -void main() { - runApp(LogoApp()); -} diff --git a/src/_includes/code/animation/animate4/pubspec.yaml b/src/_includes/code/animation/animate4/pubspec.yaml deleted file mode 100644 index 34941f10b8..0000000000 --- a/src/_includes/code/animation/animate4/pubspec.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: animate4 -description: A new Flutter project. - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/. - - # To add assets from package dependencies, first ensure the asset - # is in the lib/ directory of the dependency. Then, - # refer to the asset with a path prefixed with - # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not - # include `lib/` in the asset path. - # - # Here is an example: - # - # assets: - # - packages/PACKAGE_NAME/path/to/asset - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 diff --git a/src/_includes/code/animation/animate5/main.dart b/src/_includes/code/animation/animate5/main.dart deleted file mode 100644 index 193c461a97..0000000000 --- a/src/_includes/code/animation/animate5/main.dart +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Demonstrate an AnimatedWidget with multiple Tweens. - -import 'package:flutter/animation.dart'; -import 'package:flutter/material.dart'; - -class AnimatedLogo extends AnimatedWidget { - // Make the Tweens static because they don't change. - static final _opacityTween = Tween(begin: 0.1, end: 1.0); - static final _sizeTween = Tween(begin: 0.0, end: 300.0); - - AnimatedLogo({Key key, Animation animation}) - : super(key: key, listenable: animation); - - Widget build(BuildContext context) { - final Animation animation = listenable; - return Center( - child: Opacity( - opacity: _opacityTween.evaluate(animation), - child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), - height: _sizeTween.evaluate(animation), - width: _sizeTween.evaluate(animation), - child: FlutterLogo(), - ), - ), - ); - } -} - -class LogoApp extends StatefulWidget { - _LogoAppState createState() => _LogoAppState(); -} - -class _LogoAppState extends State with SingleTickerProviderStateMixin { - AnimationController controller; - Animation animation; - - initState() { - super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); - animation = CurvedAnimation(parent: controller, curve: Curves.easeIn); - - animation.addStatusListener((status) { - if (status == AnimationStatus.completed) { - controller.reverse(); - } else if (status == AnimationStatus.dismissed) { - controller.forward(); - } - }); - - controller.forward(); - } - - Widget build(BuildContext context) { - return AnimatedLogo(animation: animation); - } - - dispose() { - controller.dispose(); - super.dispose(); - } -} - -void main() { - runApp(LogoApp()); -} diff --git a/src/_includes/code/animation/animate5/pubspec.yaml b/src/_includes/code/animation/animate5/pubspec.yaml deleted file mode 100644 index 84b1d58802..0000000000 --- a/src/_includes/code/animation/animate5/pubspec.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: animate5 -description: A new Flutter project. - -dependencies: - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/. - - # To add assets from package dependencies, first ensure the asset - # is in the lib/ directory of the dependency. Then, - # refer to the asset with a path prefixed with - # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not - # include `lib/` in the asset path. - # - # Here is an example: - # - # assets: - # - packages/PACKAGE_NAME/path/to/asset - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 diff --git a/src/docs/development/ui/animations/tutorial.md b/src/docs/development/ui/animations/tutorial.md index 764e3d8a01..4b073fcdc9 100644 --- a/src/docs/development/ui/animations/tutorial.md +++ b/src/docs/development/ui/animations/tutorial.md @@ -2,12 +2,14 @@ title: Animations tutorial short-title: Tutorial description: A tutorial showing how to build explicit animations in Flutter. +diff2html: true --- {% assign api = 'https://docs.flutter.io/flutter' -%} -{% capture code -%} {{site.repo.this}}/tree/{{site.branch}}/src/_includes/code {%- endcapture -%} {% capture examples -%} {{site.repo.this}}/tree/{{site.branch}}/examples {%- endcapture -%} + + {{site.alert.secondary}}

What you’ll learn

@@ -78,28 +80,25 @@ An `Animation` object knows nothing about rendering or `build()` functions. A [CurvedAnimation][] defines the animation's progress as a non-linear curve. - -{% prettify dart %} -final CurvedAnimation curve = - CurvedAnimation(parent: controller, curve: Curves.easeIn); -{% endprettify %} + +```dart +animation = CurvedAnimation(parent: controller, curve: Curves.easeIn); +``` - + ``` +{{site.alert.end}} `CurvedAnimation` and `AnimationController` (described in the next section) are both of type `Animation`, so you can pass them interchangeably. @@ -114,11 +113,11 @@ an `AnimationController` linearly produces the numbers from 0.0 to 1.0 during a given duration. For example, this code creates an Animation object, but does not start it running: - -{% prettify dart %} -final AnimationController controller = AnimationController( - duration: const Duration(milliseconds: 2000), vsync: this); -{% endprettify %} + +```dart +controller = + AnimationController(duration: const Duration(seconds: 2), vsync: this); +``` `AnimationController` derives from `Animation`, so it can be used wherever an `Animation` object is needed. However, the `AnimationController` @@ -133,7 +132,7 @@ When creating an `AnimationController`, you pass it a `vsync` argument. The presence of `vsync` prevents offscreen animations from consuming unnecessary resources. You can use your stateful object as the vsync by adding `SingleTickerProviderStateMixin` to the class definition. You can see an example -of this in [animate1]({{code}}/animation/animate1/main.dart) on GitHub. +of this in [animate1]({{examples}}/animation/animate1/lib/main.dart) on GitHub. {% comment %} The `vsync` object ties the ticking of the animation controller to @@ -165,10 +164,10 @@ a different range or a different data type, you can use a [Tween][] to configure an animation to interpolate to a different range or data type. For example, the following `Tween` goes from -200.0 to 0.0: - -{% prettify dart %} -final Tween doubleTween = Tween(begin: -200.0, end: 0.0); -{% endprettify %} + +```dart +tween = Tween(begin: -200, end: 0); +``` A `Tween` is a stateless object that takes only `begin` and `end`. The sole job of a `Tween` is to define a mapping from an input range to an output range. The @@ -178,11 +177,10 @@ A `Tween` inherits from `Animatable`, not from `Animation`. An Animatable, like Animation, doesn't have to output double. For example, `ColorTween` specifies a progression between two colors. - -{% prettify dart %} -final Tween colorTween = - ColorTween(begin: Colors.transparent, end: Colors.black54); -{% endprettify %} + +```dart +colorTween = ColorTween(begin: Colors.transparent, end: Colors.black54); +``` A `Tween` object does not store any state. Instead, it provides the `evaluate(Animation animation)` method that applies the mapping function @@ -197,25 +195,27 @@ To use a `Tween` object, call `animate()` on the `Tween`, passing in the controller object. For example, the following code generates the integer values from 0 to 255 over the course of 500 ms. - -{% prettify dart %} -final AnimationController controller = AnimationController( + +```dart +AnimationController controller = AnimationController( duration: const Duration(milliseconds: 500), vsync: this); Animation alpha = IntTween(begin: 0, end: 255).animate(controller); -{% endprettify %} +``` -Notice that `animate()` returns an Animation, not an Animatable. +{{site.alert.note}} + The `animate()` method returns an [Animation][], not an [Animatable][]. +{{site.alert.end}} The following example shows a controller, a curve, and a `Tween`: - -{% prettify dart %} -final AnimationController controller = AnimationController( + +```dart +AnimationController controller = AnimationController( duration: const Duration(milliseconds: 500), vsync: this); final Animation curve = CurvedAnimation(parent: controller, curve: Curves.easeOut); Animation alpha = IntTween(begin: 0, end: 255).animate(curve); -{% endprettify %} +``` ### Animation notifications @@ -251,136 +251,136 @@ Each section provides a link to the source code for that example. * To make a class private, start its name with an underscore (`_`). {{site.alert.end}} -So far you've learned how to generate a sequence of numbers over time. -Nothing has been rendered to the screen. To render with an -`Animation` object, store the `Animation` object as a -member of your Widget, then use its value to decide how to draw. +So far you've learned how to generate a sequence of numbers over time. Nothing +has been rendered to the screen. To render with an `Animation` object, store the +`Animation` object as a member of your widget, then use its value to decide how +to draw. -Consider the following application that draws the Flutter logo without -animation: +Consider the following app that draws the Flutter logo without animation: - -{% prettify dart %} + +```dart import 'package:flutter/material.dart'; +void main() => runApp(LogoApp()); + class LogoApp extends StatefulWidget { _LogoAppState createState() => _LogoAppState(); } class _LogoAppState extends State { + @override Widget build(BuildContext context) { return Center( child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), - height: 300.0, - width: 300.0, + margin: EdgeInsets.symmetric(vertical: 10), + height: 300, + width: 300, child: FlutterLogo(), ), ); } } +``` -void main() { - runApp(LogoApp()); -} -{% endprettify %} +**App source:** [animate0]({{examples}}/animation/animate0) -The following shows the same code modified to animate the -logo to grow from nothing to full size. When -defining an `AnimationController`, you must pass in a `vsync` object. -The `vsync` parameter is described in the +The following shows the same code modified to animate the logo to grow from +nothing to full size. When defining an `AnimationController`, you must pass in a +`vsync` object. The `vsync` parameter is described in the [AnimationController](#animationcontroller) section. The changes from the non-animated example are highlighted: - -{% prettify dart %} -[[highlight]]import 'package:flutter/animation.dart';[[/highlight]] -import 'package:flutter/material.dart'; - -class LogoApp extends StatefulWidget { - _LogoAppState createState() => _LogoAppState(); -} - -class _LogoAppState extends State [[highlight]]with SingleTickerProviderStateMixin[[/highlight]] { - [[highlight]]Animation animation;[[/highlight]] - [[highlight]]AnimationController controller;[[/highlight]] - - [[highlight]]initState() {[[/highlight]] - [[highlight]]super.initState();[[/highlight]] - [[highlight]]controller = AnimationController([[/highlight]] - [[highlight]]duration: const Duration(milliseconds: 2000), vsync: this);[[/highlight]] - [[highlight]]animation = Tween(begin: 0.0, end: 300.0).animate(controller)[[/highlight]] - [[highlight]]..addListener(() {[[/highlight]] - [[highlight]]setState(() {[[/highlight]] - [[highlight]]// the state that has changed here is the animation object’s value[[/highlight]] - [[highlight]]});[[/highlight]] - [[highlight]]});[[/highlight]] - [[highlight]]controller.forward();[[/highlight]] - [[highlight]]}[[/highlight]] - - Widget build(BuildContext context) { - return Center( - child: Container( - margin: EdgeInsets.symmetric(vertical: 10.0), - height: [[highlight]]animation.value,[[/highlight]] - width: [[highlight]]animation.value,[[/highlight]] - child: FlutterLogo(), - ), - ); - } - - [[highlight]]dispose() {[[/highlight]] - [[highlight]]controller.dispose();[[/highlight]] - [[highlight]]super.dispose();[[/highlight]] - } -} - -void main() { - runApp(LogoApp()); -} -{% endprettify %} - -The `addListener()` function calls `setState()`, so every time the -Animation generates a new number, the current frame is marked dirty, -which forces `build()` to be called again. -In `build()`, the container changes size because its height and width -now use `animation.value` instead of a hardcoded value. -Dispose of the controller when the animation is finished to prevent -memory leaks. + +```diff +--- animate0/lib/main.dart ++++ animate1/lib/main.dart +@@ -1,3 +1,4 @@ ++import 'package:flutter/animation.dart'; + import 'package:flutter/material.dart'; + + void main() => runApp(LogoApp()); +@@ -6,16 +7,39 @@ + _LogoAppState createState() => _LogoAppState(); + } + +-class _LogoAppState extends State { ++class _LogoAppState extends State with SingleTickerProviderStateMixin { ++ Animation animation; ++ AnimationController controller; ++ ++ @override ++ void initState() { ++ super.initState(); ++ controller = ++ AnimationController(duration: const Duration(seconds: 2), vsync: this); ++ animation = Tween(begin: 0, end: 300).animate(controller) ++ ..addListener(() { ++ setState(() { ++ // The state that has changed here is the animation object’s value. ++ }); ++ }); ++ controller.forward(); ++ } ++ + @override + Widget build(BuildContext context) { + return Center( + child: Container( + margin: EdgeInsets.symmetric(vertical: 10), +- height: 300, +- width: 300, ++ height: animation.value, ++ width: animation.value, + child: FlutterLogo(), + ), + ); + } ++ ++ @override ++ void dispose() { ++ controller.dispose(); ++ super.dispose(); ++ } + } +``` + +**App source:** [animate1]({{examples}}/animation/animate1) + +The `addListener()` function calls `setState()`, so every time the `Animation` +generates a new number, the current frame is marked dirty, which forces +`build()` to be called again. In `build()`, the container changes size because +its height and width now use `animation.value` instead of a hardcoded value. +Dispose of the controller when the animation is finished to prevent memory +leaks. With these few changes, you’ve created your first animation in Flutter! -You can find the source for this example, -[animate1.]({{site.repo.this}}/tree/{{site.branch}}/src/_includes/code/animation/animate1/main.dart)