Flutter动画: Animation动画基础(三)

我的博客

本章再练习几个隐式和显式动画, 并且集合二个或多个Animation对象完成交织动画。

首先来看AnimatedContainer

AnimatedContainer

基本上看过Flutter官方动画教程的, 都看过关于AnimatedContainer的示例, 我们也来做一个。 AnimatedContainer是一个隐式动画对象, 无需设置AnimationController来手动控制动画的启动与停止, 只需要设计数值的起始和终值。

AnimatedContainer, 从名字看, 是将常用的Container组件进行了动画处理, 实际也确实如此。 原来Container的大部分参数都可以设置动画数值。 同时还增加了一个非常好的控制方法onEnd:(){}, 方便在收到动画结束信息后, 可以切换其它操作。

import 'package:flutter/material.dart';

class MyAnimatedContainerDemo extends StatefulWidget {
  @override
  _MyAnimatedContainerDemoState createState() =>
      _MyAnimatedContainerDemoState();
}

class _MyAnimatedContainerDemoState extends State
    with SingleTickerProviderStateMixin {
  bool isActive = false;
  final Duration duration = Duration(milliseconds: 2000);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('点击缩放-AnimatedContainer组件')),
      body: Center(
        child: AnimatedContainer(
          duration: duration,
          width: isActive ? 200 : 100,
          height: isActive ? 200 : 100,
          decoration: BoxDecoration(
              color: isActive ? Colors.red : Colors.blue,
              borderRadius: BorderRadius.circular(isActive ? 20 : 0)),
          onEnd: () {
            setState(() {
              isActive = !isActive;
            });
          },
          child: InkWell(
            onTap: () {
              setState(() {
                isActive = !isActive;
              });
            },
            child: CircleAvatar(
              backgroundImage: AssetImage('assets/images/head.jpg'),
            ),
          ),
        ),
      ),
    );
  }
}

效果如下:

AnimatedContainer

从代码中可以看到, 我们对AnimatedContainer的width, height, color和borderRadius都进行了设置, 并且在动画结束(onEnd)的时候, 对数值进行了反转, 因此带动动画也Reverse了。

RotationTransition

RotationTransition是一个旋转组件, 其child默认围绕中心旋转。 RotationTransition的参数turns是一个Animation对象, 用于更新当前旋转的角度。看示例。

import 'package:flutter/material.dart';

class MyRotationTransitionDemo extends StatefulWidget {
  @override
  _MyRotationTransitionDemoState createState() =>
      _MyRotationTransitionDemoState();
}

class _MyRotationTransitionDemoState extends State
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation turns;
  Duration duration = Duration(milliseconds: 3000);
  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: duration);
    turns = Tween(begin: 0.0, end: 1.0).animate(controller);
    controller.repeat();
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('RotationTransition组件')),
      body: Center(
        child: RotationTransition(
          turns: turns,
          child: Container(
            width: 200,
            height: 200,
            padding: EdgeInsets.all(5.0),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              border: Border.all(color: Colors.blue),
            ),
            child: CircleAvatar(
              backgroundImage: AssetImage('assets/images/head.jpg'),
            ),
          ),
        ),
      ),
    );
  }
}

效果如下:

RotationTransition

复杂交织(组合)动画

现在我们来做一个比较复杂的交织(组合)动画。 先放效果图。

complex_animation

从图中可以看到,

  • 外部圈内的颜色周期性变化
  • 头像周期性的缩小、放大
  • 头像周期性的旋转

其实这是一个比较简单的交织(组合)动画, 只是简单的将AnimatedContainer、ScaleTransition和RotationTransition进行了组合而已, 三者没有关联, 各自负责自己的动画。

来看代码。

import 'dart:async';

import 'package:flutter/material.dart';

class MyComplexAnimationDemo extends StatefulWidget {
  @override
  _MyComplexAnimationDemoState createState() => _MyComplexAnimationDemoState();
}

class _MyComplexAnimationDemoState extends State
    with TickerProviderStateMixin {
  // 控制AnimatedContainer的动画
  Timer timer;
  bool isActive = true;

  // 控制widget缩放scale
  AnimationController scaleController;
  Animation scale;

  // 控制widget旋转rotation
  AnimationController rotationController;
  Animation turns;

  Duration duration = Duration(milliseconds: 1000);

  @override
  void initState() {
    super.initState();
    // 定时让AnimatedContainer的参数做变动
    timer = Timer.periodic(duration, (t) {
      setState(() {
        isActive = !isActive;
      });
    });

    // 设置缩放控制器和数值区间
    scaleController = AnimationController(vsync: this, duration: duration);
    scale = Tween(begin: 0.8, end: 1.0).animate(scaleController);
    scaleController.repeat(reverse: true);

    // 设置旋转控制器和数值区间, 旋转速度慢一点(持续时间长一点), 不做状态监听, 让动画一直重复就好
    rotationController =
        AnimationController(vsync: this, duration: duration * 8);
    turns = Tween(begin: 1.0, end: 0.0).animate(rotationController);
    rotationController.repeat();
  }

  @override
  void dispose() {
    timer?.cancel();
    timer = null;
    scaleController?.dispose();
    rotationController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('复杂交织动画')),
      body: Center(
        child: AnimatedContainer(
          width: 200,
          height: 200,
          padding: EdgeInsets.all(10),
          duration: duration,
          decoration: BoxDecoration(
            color: isActive ? Colors.blue : Colors.grey,
            shape: BoxShape.circle,
          ),
          child: ScaleTransition(
            scale: scale,
            child: RotationTransition(
              turns: turns,
              child: CircleAvatar(
                backgroundImage: AssetImage('assets/images/head.jpg'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

好吧, 文章已经够长了, 后面抽空再写一篇带顺序关系的动画。

你可能感兴趣的:(Flutter动画: Animation动画基础(三))