0

如何在每帧刷新时间获得持久的滴答声。例如,在 Flame 游戏引擎update中,大约每秒钟调用一次方法,并传递一个经过时间 1/60的值。 我想实现一个风扇旋转的简单动画。我想根据用户输入改变它的旋转速度。我的想法是,在每个滴答声中,我都会以固定值旋转扇形图像/容器。随着用户增加速度,我将增加乘数。使用 Flame 引擎或 Flare 之类的选项很少,但它们似乎有点矫枉过正。另外,我可以使用,但是很少有开销,比如在完成并转发动画时反转动画等等...... dt

SingleTickerProviderMixin

我认为会有一个简单的解决方案,它会在大约每 1/60 秒发生的每个帧刷新时间通知我,并将经过的时间dt(大约 167 毫秒左右)传递给我。

4

2 回答 2

2

一个很好的方法(没有动画小部件)是实现一个带有 Stream 的 Timer;请参见下面的示例:

import 'package:flutter/material.dart';
import "dart:async";

const frequency = Duration(milliseconds: 50);

void main() => runApp(
      MaterialApp(
        home: Material(
          child: Center(
            child: Container(
              color: Colors.white,
              child: MyWidget(),
            ),
          ),
        ),
      ),
    );

class MyWidget extends StatefulWidget {
  MyWidgetState createState() => MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  final StreamController<double> _streamer =
      StreamController<double>.broadcast();

  Timer timer;

  double _rotation = 0.0;

  @override
  void initState() {
    super.initState();

    timer = Timer.periodic(frequency, (t) {
      _rotation++;
      _streamer.add(1);
    });
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<double>(
        initialData: 0,
        stream: _streamer.stream,
        builder: (context, snapshot) {
          return Transform(
            transform: Matrix4.rotationZ(_rotation),
            child: Text('Hello, World!'),
          );
        });
  }
}
于 2020-05-08T14:53:26.757 回答
0

如果您复制此代码,我还将确保实现 dispose() 回调。您需要确保取消()任何正在运行的计时器以防止奇怪的行为,否则它们将成为内存泄漏的来源。

计时器 = null ; 并不总是需要,但在某些情况下,状态对象将持有对计时器 var 本身的引用,并且还会导致内存泄漏。例如,如果您在计时器回调主体中捕获计时器变量。

例子:

@override
  void dispose() {
    timer?.cancel();
    timer = null;
    super.dispose();
  }
于 2020-10-03T15:58:10.463 回答