一统天下 flutter - 动画: Stagger - 复合动画,即一个 AnimationController 控制多个动画

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

一统天下 flutter - 动画: Stagger - 复合动画,即一个 AnimationController 控制多个动画

示例如下:

lib\animation\stagger.dart

/*
 * Stagger - 复合动画,即一个 AnimationController 控制多个动画
 *
 * 通过 Interval 定义 CurvedAnimation 的 curve
 * 其用于指定 CurvedAnimation 相对于 AnimationController 的开始点和结束点
 */

import 'package:flutter/material.dart';

class StaggerDemo extends StatefulWidget {
  const StaggerDemo({super.key});

  @override
  State<StaggerDemo> createState() => _StaggerDemoState();
}

class _StaggerDemoState extends State<StaggerDemo> with SingleTickerProviderStateMixin {

  late AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(duration: const Duration(milliseconds: 10000), vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Staggered Animation'),
      ),
      body: Center(
        child: Container(
          color: Colors.grey,
          width: 300.0,
          height: 300.0,
          child: StaggerAnimation(controller: _controller),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _controller.repeat(reverse: true);
        },
        child: const Icon(Icons.play_arrow),
      ),
    );
  }

  @override
  void dispose() {
    /// 清理 AnimationController
    _controller.dispose();
    super.dispose();
  }
}


/// 用于演示复合动画,即一个 AnimationController 控制多个动画
class StaggerAnimation extends StatelessWidget {
  StaggerAnimation({super.key, required this.controller})
      :
  opacity = Tween<double>(begin: 0.0, end: 1.0,).animate(CurvedAnimation(parent: controller,
    curve: const Interval(0.0, 0.100, curve: Curves.bounceInOut,),
  ),),

  width = Tween<double>(begin: 50.0, end: 150.0,).animate(CurvedAnimation(parent: controller,
    /// Interval 用于指定动画相对于 AnimationController 的开始点和结束点
    ///   因为 AnimationController 指定了动画为 10 秒
    ///   所以此动画会开始在 0.125 * 10 = 1.25 秒,结束在 0.250 * 10 = 2.5 秒
    curve: const Interval(0.125, 0.250, curve: Curves.bounceInOut,),
  ),),

  height = Tween<double>(begin: 50.0, end: 150.0).animate(CurvedAnimation(parent: controller,
    curve: const Interval(0.250, 0.375, curve: Curves.bounceInOut,),
  ),),

  padding = EdgeInsetsTween(begin: const EdgeInsets.only(bottom: 16.0), end: const EdgeInsets.only(bottom: 75.0),).animate(CurvedAnimation(parent: controller,
    curve: const Interval(0.250, 0.375, curve: Curves.bounceInOut,),
  ),),

  borderRadius = BorderRadiusTween(begin: BorderRadius.circular(4.0), end: BorderRadius.circular(75.0),).animate(CurvedAnimation(parent: controller,
    curve: const Interval(0.375, 0.500, curve: Curves.bounceInOut,),
  ),),

  color = ColorTween(begin: Colors.red, end: Colors.green,).animate(CurvedAnimation(parent: controller,
    curve: const Interval(0.500, 0.750, curve: Curves.bounceInOut,),
  ),);

  final Animation<double> controller;
  final Animation<double> opacity;
  final Animation<double> width;
  final Animation<double> height;
  final Animation<EdgeInsets> padding;
  final Animation<BorderRadius?> borderRadius;
  final Animation<Color?> color;

  Widget _buildAnimation(BuildContext context, Widget? child) {
    return Container(
      padding: padding.value,
      alignment: Alignment.bottomCenter,
      child: Opacity(
        opacity: opacity.value,
        child: Container(
          width: width.value,
          height: height.value,
          decoration: BoxDecoration(
            color: color.value,
            border: Border.all(
              color: Colors.blue,
              width: 3.0,
            ),
            borderRadius: borderRadius.value,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: _buildAnimation,
    );
  }
}

源码 https://github.com/webabcd/flutter_demo
作者 webabcd

posted @ 2023-03-22 11:31  webabcd  阅读(179)  评论(0编辑  收藏  举报