Flutter属性动画

前言

本质上来说 flutter并没有属性动画这个玩意,但是这个思路和android的属性动画差不多,就这样写了

目标功能

实现一个动画 5-4-3-2-1 倒计时 同时旋转加缩放,旋转先顺时针再反向

主要用到的api

  • AnimationController 动画控制器,就是控制线性产生 0-1之间的小数
  • CurvedAnimation 插值计算器,这个和android原生的插值计算器类似,作用就是传入 一个 0-1之间的小数,返回一个经过插值处理的值
  • Tween 给定 begin 和 end ,传入小数,返回begin 和end 之间的一个值
  • AnimatedBuilder 绑定 AnimationController,AnimationController变化时会刷新
  • TickerProviderStateMixin state绑定的view 在屏幕外时依然动画

比较有意思的代码

这里自定义了一个 插值计算器 代码如下

class ReversCurve extends Curve {

  const ReversCurve(this.threshold) : assert(threshold != null);

  final double threshold;

  @override
  double transformInternal(double t) {
    assert(threshold > 0.0);
    assert(threshold < 1.0);
    if (t<=threshold){
      return (t/threshold);
    }else {
      return (1-t)/(1-threshold);
    }
  }
}

实现的是先正向后反向

整体代码

import 'package:flutter/material.dart';
import 'dart:math';

class AnimationView extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return AnimationViewState();
  }
}
class ReversCurve extends Curve {
  const ReversCurve(this.threshold) : assert(threshold != null);

  final double threshold;

  @override
  double transformInternal(double t) {
    assert(threshold > 0.0);
    assert(threshold < 1.0);
    if (t<=threshold){
      return (t/threshold);
    }else {
      return (1-t)/(1-threshold);
    }
  }
}
class AnimationViewState extends State<AnimationView>
    with TickerProviderStateMixin {
  AnimationController controller;

  var scaleAnimation = Tween(begin: 1.0, end: 2.0);
  var rotationAnimation = Tween(begin: 0.0, end: 2 * pi);
  IntTween countDown=IntTween(begin:5,end:1);
  double screenHeight = 0;

  CurvedAnimation cur;

  AnimationViewState() : super() {
    controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));
   cur= CurvedAnimation(parent: controller, curve:ReversCurve(0.6) );
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  void _startAnimation() async {
    try {
      controller.reset();
    } catch (e) {
      print(e);
    }
    try {
      await controller.forward().orCancel;
    } catch (e) {
      print(e);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    if (screenHeight == 0.0) {
      screenHeight = MediaQuery.of(context).size.height * 0.4;
    }
    return Column(
      children: <Widget>[
        Container(
          height: screenHeight,
          child: Center(
            child: AnimatedBuilder(
                animation: controller,
                builder: (context, widgt) {
                  return Transform(
                    transform: Matrix4.rotationZ(
                        rotationAnimation.evaluate(cur)),
                    alignment: Alignment.center,
                    child: Transform.scale(
                      scale: scaleAnimation.evaluate(controller),
                      child: Text("${countDown.evaluate(controller)}"),
                    ),
                  );
                }),
          ),
        ),
        RaisedButton(
          child: Text("rotate"),
          onPressed: _startAnimation,
        )
      ],
    );
  }
}

效果

效果图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值