Flutter代码创建缓慢的动画。这是怎么了?

时间:2019-06-12 12:19:31

标签: animation flutter dart accelerometer

我创建了一个颤动小部件,可使用加速度计移动圆。这非常麻烦,因为在移动电话时必须使用setState更改圆圈的位置。除了创建它之外,还有其他选择吗?

我在这里使用了AnimatedBuilder,但是不确定在设备平稳移动时如何改变圆的位置。

class _AnimationWidgetState extends State<AnimationWidget>
    with TickerProviderStateMixin {
  AnimationController _animeController;
  Animation _anime;
  double x = 0.0, y = 0.0;
  @override
  void initState() {
    super.initState();
    _animeController =
        AnimationController(vsync: this, duration: const Duration(seconds: 2));
    _anime = Tween(begin: 0.5, end: 0.5).animate(
        CurvedAnimation(parent: _animeController, curve: Curves.ease));
    accelerometerEvents.listen((AccelerometerEvent event) {
      var a = ((event.x * 100).round() / 100).clamp(-1.0, 1.0) * -1;
      var b = ((event.y * 100).round() / 100).clamp(-1.0, 1.0);
      if ((x - a).abs() > 0.02 || (y - b).abs() > 0.02) {
        setState(() {
          x = a; y = b;
        });
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    _animeController.forward();
    final double width = MediaQuery.of(context).size.width;
    final double height = MediaQuery.of(context).size.height;
    return AnimatedBuilder(
      animation: _animeController,
      builder: (context, child) {
        return Scaffold(
          body: Transform(
            transform: Matrix4.translationValues(
                _anime.value * width * x, _anime.value * height * y, 0.0),
            child: Center(
              child: CircleAvatar(
                radius: 15.0,
                backgroundColor: Colors.green,
              ),
            ),
          ),
        );
      },
    );
  }
}

动画一点都不流畅。这是因为我必须使用setState,但是圆环的移动仍在按需进行。

1 个答案:

答案 0 :(得分:0)

使用AnimationController的全部目的是监听其事件-AnimatedBuilder就是这样做并相应地重建其子树。

我将在此处发布有关代码更改内容的总体建议。


删除setState-这就是使您的整个版式重新生成的全部内容,即滞后。

还触发_animeController侦听器,即您的情况下的AnimatedBuilder-自行重建。

accelerometerEvents.listen((AccelerometerEvent event) {
  var a = ((event.x * 100).round() / 100).clamp(-1.0, 1.0) * -1;
  var b = ((event.y * 100).round() / 100).clamp(-1.0, 1.0);
  if ((x - a).abs() > 0.02 || (y - b).abs() > 0.02) {
    x = a; y = b;
    _animeController.value = _animeController.value; // Trigger controller's listeners
  }
});

initState而不是build开始动画。这是在您的情况下产生延迟的第二件事。 .forward触发窗口小部件的重建,从而导致无限循环。

@override
void initState() {
  super.initState();
  _animeController.forward();
}

使用您的child的{​​{1}}属性来节省每次重建头像块时的资源。另外,我不确定AnimatedBuilder是做什么用的-如果不需要,请删除它。

Scaffold

跟随Official Animations Tutorial掌握Flutter动画。

让我知道这是否有帮助。