likes
comments
collection
share

flutter实现简单的旋转动画

作者站长头像
站长
· 阅读数 17

前言

flutter实现简单的旋转动画,和大家一起学习探讨。

先上效果图:

flutter实现简单的旋转动画

概述

Flutter中对动画进行了抽象,主要涉及Animation、Curve、Controller、Tween这四个角色。

Animation对象是一个在一段时间内依次生成一个区间(Tween)之间值的类,
它的四种状态:
dismissed:动画初始状态
forward:动画从头到尾播放状态
reverse:动画从尾到头播放状态
completed:动画完成状态

Tween ,它主要是弥补 AnimationController 动画值只能为 double 类型的不足,
我的理解是animation是以动画的时间区间为X轴,根据设定好的Tween的开始结束值为Y轴,
框架自动计算如何从开始点过渡到结束点。

需要注意的是当创建一个AnimationController时,需要传递一个vsync参数,存在vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源。通过将SingleTickerProviderStateMixin添加到类定义中,可以将stateful对象作为vsync的值。如果要使用自定义的State对象作为vsync时,请包含TickerProviderStateMixin。

class _AnimationDemoState extends State<AnimationDemo>  with SingleTickerProviderStateMixin

_animationController = AnimationController(duration: Duration(seconds: 300), vsync: this);

通过Animation抽象类的addStatusListener();它可以给Animation添加“动画状态改变”监听器;动画开始、结束、正向或反向时会调用状态改变的监听器。

    _animation =  Tween<double>(
      begin: 1,
      end: 300,
    ).animate(_animationController)..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        // 动画完成后反转
        _animationController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        // 反转回初始状态时继续播放,实现无限循环
        _animationController.forward();
      }

通过点击按钮控制AnimationController控制动画,启动forward()、停止stop()

        child: GestureDetector(
          onTap: (){
            if(isStartTrain == false){
              _animationController.forward();
            }else{
              _animationController.stop();
            }
            setState(() {
              isStartTrain = !isStartTrain;
            });
          },

以下是demo代码

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/screenutil.dart';

class AnimationDemo extends StatefulWidget {
  AnimationDemo({Key key}) : super(key: key);

  @override
  _AnimationDemoState createState() {
    return _AnimationDemoState();
  }
}

class _AnimationDemoState extends State<AnimationDemo>  with SingleTickerProviderStateMixin{

  bool isStartTrain = false;
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() {

    _animationController =
        AnimationController(duration: Duration(seconds: 300), vsync: this);

    _animation =  Tween<double>(
      begin: 1,
      end: 300,
    ).animate(_animationController)..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        // 动画完成后反转
        _animationController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        // 反转回初始状态时继续播放,实现无限循环
        _animationController.forward();
      }

    });



    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: GestureDetector(
          onTap: (){
            if(isStartTrain == false){
              _animationController.forward();
            }else{
              _animationController.stop();
            }
            setState(() {
              isStartTrain = !isStartTrain;
            });
          },
          child: Stack(
            children: [
              Positioned(
                child: Center(
                  child: RotationTransition(
                    //设置动画的旋转中心
                    alignment: Alignment.center,
                    //动画控制器
                    turns: _animation,
                    child: Container(
                      width: ScreenUtil().setWidth(180),
                      height: ScreenUtil().setWidth(180),
                      decoration: BoxDecoration(
                        image:DecorationImage(
                          image: AssetImage("assets/images/bg_timer.png"),
                          fit: BoxFit.cover,
                        ),
                        // color: Color(0xFFFF542C),
                        // borderRadius: BorderRadius.circular(1000)
                      ),

                    ),
                  ),
                ),
              ),
              Positioned(
                child: Center(
                    child: Text(
                      '${isStartTrain?"结束":"开始"}',
                      style: TextStyle(
                          color: Color(0xFF201E24),
                          fontSize: ScreenUtil().setSp(28)),
                    )),
              )
            ],

          ),
        ),
      ),
    );
  }
}

欢迎大家和我一起学习分享flutter,项目会持续更新新的学习demo

此项目的github地址:项目地址

下面是我们的公众号:flutter编程笔记(code9871)

公众号 不定期分享自己的学习想法

转载自:https://juejin.cn/post/6927450385267294216
评论
请登录