欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-16 21:50:22
...

我的博客

本章再练习几个隐式和显式动画, 并且集合二个或多个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<MyAnimatedContainerDemo>
    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<double>对象, 用于更新当前旋转的角度。看示例。

 

import 'package:flutter/material.dart';

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

class _MyRotationTransitionDemoState extends State<MyRotationTransitionDemo>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<double> turns;
  Duration duration = Duration(milliseconds: 3000);
  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: duration);
    turns = Tween<double>(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

复杂交织(组合)动画

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

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

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<MyComplexAnimationDemo>
    with TickerProviderStateMixin {
  // 控制AnimatedContainer的动画
  Timer timer;
  bool isActive = true;

  // 控制widget缩放scale
  AnimationController scaleController;
  Animation<double> scale;

  // 控制widget旋转rotation
  AnimationController rotationController;
  Animation<double> 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<double>(begin: 0.8, end: 1.0).animate(scaleController);
    scaleController.repeat(reverse: true);

    // 设置旋转控制器和数值区间, 旋转速度慢一点(持续时间长一点), 不做状态监听, 让动画一直重复就好
    rotationController =
        AnimationController(vsync: this, duration: duration * 8);
    turns = Tween<double>(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'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

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



作者:朋朋彭哥
链接:https://www.jianshu.com/p/1d695c17f535
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。