command + option + L 格式化代码

option + enter 代码补全

隐式动画用animated开头

补间动画

  1. child: TweenAnimationBuilder(
  2. tween: Tween<double>(begin: 50, end: 100),
  3. duration: const Duration(seconds: 4),
  4. builder: (BuildContext context, double? value, Widget? child) {
  5. return Container(
  6. width: 300,
  7. height: 200,
  8. color: Colors.blue,
  9. child: Center(
  10. child: Text(
  11. "Hi",
  12. style: TextStyle(fontSize: value),
  13. )),
  14. );
  15. }),

Transform.rotate, scale,translate

  1. child: TweenAnimationBuilder(
  2. tween: Tween<double>(begin: 0, end: 6.28),
  3. duration: const Duration(seconds: 4),
  4. builder: (BuildContext context, double? value, Widget? child) {
  5. return Container(
  6. width: 300,
  7. height: 200,
  8. color: Colors.blue,
  9. child: Center(
  10. child: Transform.rotate(
  11. angle: value??0,//取值是0--2pi之间,0 -- 6.28
  12. child: const Text(
  13. "Hi",
  14. style: TextStyle(fontSize: 50),
  15. )),
  16. ));
  17. }),

例子:

  1. body: Center(
  2. child: Container(
  3. width: 300,
  4. height: 120,
  5. color: Colors.blue,
  6. child: TweenAnimationBuilder(
  7. duration: const Duration(seconds: 1),
  8. tween: Tween<double>(begin: 7, end: 7),
  9. builder: (BuildContext context, double? value, Widget? child) {
  10. final whole = value! ~/ 1;
  11. final decimal = value - whole;
  12. return Stack(children: [
  13. Positioned(
  14. top: -100 * decimal,//0 -> -100
  15. child: Opacity(
  16. opacity: 1 - decimal,//1 -> 0,
  17. child: Text(
  18. "$whole",
  19. style: const TextStyle(fontSize: 100),
  20. ),
  21. ),
  22. ),
  23. Positioned(
  24. top: 100 - decimal * 100,//100 -> 0,
  25. child: Opacity(
  26. opacity: decimal,// 0 -> 1,
  27. child: Text(
  28. "${whole + 1}",
  29. style: const TextStyle(fontSize: 100),
  30. ),
  31. ),
  32. ),
  33. ]);
  34. },
  35. ),
  36. ),
  37. ),

上下滚动的计数器:

  1. class Counter extends StatelessWidget {
  2. final int value;
  3. final Duration duration;
  4. const Counter({required this.duration, required this.value, Key? key})
  5. : super(key: key);
  6. @override
  7. Widget build(BuildContext context) {
  8. return TweenAnimationBuilder(
  9. duration: duration,
  10. tween: Tween<double>(end: value.toDouble()),
  11. builder: (BuildContext context, double? value, Widget? child) {
  12. final whole = value! ~/ 1;
  13. final decimal = value - whole;
  14. return Stack(children: [
  15. Positioned(
  16. top: -100 * decimal, //0 -> -100
  17. child: Opacity(
  18. opacity: 1 - decimal, //1 -> 0,
  19. child: Text(
  20. "$whole",
  21. style: const TextStyle(fontSize: 100),
  22. ),
  23. ),
  24. ),
  25. Positioned(
  26. top: 100 - decimal * 100, //100 -> 0,
  27. child: Opacity(
  28. opacity: decimal, // 0 -> 1,
  29. child: Text(
  30. "${whole + 1}",
  31. style: const TextStyle(fontSize: 100),
  32. ),
  33. ),
  34. ),
  35. ]);
  36. },
  37. );
  38. }
  39. }

显式动画用Transition结尾

FadeTransition, RotationTransition, ScaleTransition, SlideTransition
都可以使用AnimationController, 默认值是 0 — 1。

AnimationController 的使用:
repeat(reverse: true) 重置动画。

  1. class _MyHomePageState extends State<MyHomePage>
  2. with SingleTickerProviderStateMixin {
  3. AnimationController? _controller;
  4. bool _loading = false;
  5. @override
  6. void initState() {
  7. _controller = AnimationController(
  8. //转两圈
  9. lowerBound: 3.0,
  10. upperBound: 5.0,
  11. vsync: this,
  12. duration: const Duration(seconds: 1),
  13. );
  14. super.initState();
  15. }
  16. @override
  17. void dispose() {
  18. _controller?.dispose();
  19. super.dispose();
  20. }
  21. @override
  22. Widget build(BuildContext context) {
  23. return Scaffold(
  24. appBar: AppBar(
  25. title: Text(widget.title),
  26. ),
  27. body: Center(
  28. child: RotationTransition(
  29. turns: _controller!,
  30. child: const Icon(
  31. Icons.refresh,
  32. size: 100,
  33. )),
  34. ),
  35. floatingActionButton: FloatingActionButton(
  36. onPressed: () {
  37. if(!_loading){
  38. _controller!.repeat();
  39. }else{
  40. _controller!.stop();
  41. }
  42. _loading = !_loading;
  43. },
  44. tooltip: 'Increment',
  45. child: const Icon(Icons.add),
  46. ), // This trailing comma makes auto-formatting nicer for build methods.
  47. );
  48. }
  49. }

自动生成带有AnimationController的代码;
image.png
controller和tween一起使用:

  1. turns: _controller!.drive(Tween(begin: 0.5, end: 2.0)),

x轴移动10%

  1. child: SlideTransition(
  2. position: _controller!.drive(Tween(begin: const Offset(0,0), end: const Offset(0.1,0))),
  3. child: const Icon(
  4. Icons.refresh,
  5. size: 100,
  6. )),
  1. position: Tween(begin: const Offset(0,0), end: const Offset(0.1,0)).animate(_controller!),