Flutter 动画插值

Posted

技术标签:

【中文标题】Flutter 动画插值【英文标题】:Flutter animation interpolation 【发布时间】:2019-07-27 13:30:32 【问题描述】:

我正在尝试基于一个动画来旋转一个小部件(这不是问题的一部分,因为它通过构造函数参数处理旋转本身),该动画在先前的旋转位置和通过插件函数获得的新位置之间进行插值。该函数的值(FlutterCompass.events.listen)会定期异步更新,并且每次都会重建 Tween 对象以表示小部件位置的更新。这是我的代码:

import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
import 'package:flutter_compass/flutter_compass.dart';
import 'package:compass_test/compass.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget 
  @override
  _MyAppState createState() => new _MyAppState();


class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin
  double _direction;
  double _angle = 0.0;
  Animation<double> _animation;
  AnimationController _animationController;
  Tween<double> _tween;

  @override
  void initState() 
    super.initState();
      _animationController =
          AnimationController(duration: Duration(milliseconds: 400), vsync: this);
      _tween = Tween<double>(begin: 0.0, end: 0.0);
      _animation = _tween.animate(_animationController)
          ..addListener(() 
              setState(() 
                _angle =_animationController.value;
              );
          );
    _direction = 0;

    FlutterCompass.events.listen((double direction) 
      print(_animationController.status);
      if(_direction !=direction)
        _tween = Tween<double>(
          begin: _direction,
          end: direction);
        _animationController.reset();
        _tween.animate(_animationController);
        _animationController.forward();
      
      _direction = direction;
    );
  

  @override
  void dispose()
    _animationController.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: <Widget>[
            Center(
              child: Container(
                margin: EdgeInsets.only(top: 100),
                child: Compass(height: 300, width: 300, angleToNorth: _angle)
              )
            )
          ],
        )
      ),
    );
  

但是,正如我在一些调试中看到的那样,_animationController.value 返回的值仅在 0.0 到 1.0 之间变化,这不是我认为应该发生的:我希望它们与之前的不同将 _direction 的值更改为新的 direction 值。我怎样才能做到这一点?

提前致谢

【问题讨论】:

【参考方案1】:

这就是动画控制器的工作方式。使用一些额外的线,您甚至可以为从 0.0 到 1.0 的值变化添加一条曲线。但值总是从 0.0 到 1.0。所以你可以做的是像这样_angle = degree of angle * _animationController.value 更新_angles 值。所以假设你的角度是50度。所以当你开始你的动画时,动画控制器的值将从 0.0 开始,乘以 50,得到 0。随着动画控制器的值从 0.0 移动到 1.0,_angle 的值也会改变,最后给你 50 作为 1.0 * 50 是 50!但正如您提到的,您只想旋转您的小部件。因此,如果您想再次运行动画,您可以使用 double 类型的补间动画构建器并更新结束值,而不是这个;动画将从之前的值继续。

【讨论】:

以上是关于Flutter 动画插值的主要内容,如果未能解决你的问题,请参考以下文章

Flutter动画性能, 官方flutter基础动画在真机上能跑到20-30%CPU

Flutter 之 动画1

Flutter 尺寸缩放形状颜色阴影变换动画

Flutter 38: 图解 Flutter 基本动画

Flutter 动画使用

社区说|一起聊聊 Flutter 动画