为什么 AnimationController 需要 vsync?

Rém*_*let 7 animation flutter

使用AnimationController 时,该vsync参数的用途是什么?

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> with SingleTickerProviderStateMixin {
  AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this, // Why do we need this?
    );
  }

  // ...
}
Run Code Online (Sandbox Code Playgroud)

Rém*_*let 9

AnimationControllervsync参数有一个目的:根据外部因素控制动画的进度。

通常有三种主要用途:

  • devtools 喜欢“慢动画”,它会降低AnimationController的速度50%。
  • 小部件测试。通过使用vsync,这允许测试跳过帧以针对动画的特定状态。这既精确又不涉及等待实时。
  • 当与SingleTickerProviderStateMixin关联的小部件不再可见时,它允许动画“静音”

最后一个场景是我们的小部件需要那个SingleTickerProviderStateMixin 的主要原因。了解与动画相关联的小部件很重要。我们不能只使用从应用程序的根小部件获取的TickerProvider

通过这样vsync,这将避免我们的小部件不再可见的情况(例如,如果另一条路线被推到它的顶部),但动画仍在播放,因此使我们的屏幕不断刷新

查看该行为的一种方法是使用“性能叠加”开发工具与诸如CircularProgressIndicator 之类的小部件结合使用,后者在内部使用AnimationController

如果我们Opacity用来隐藏我们的指标(它不会暂停动画):

Opacity(
  opacity: 0,
  child: CircularProgressIndicator(),
)
Run Code Online (Sandbox Code Playgroud)

然后性能叠加显示我们的屏幕不断刷新:

不透明度性能叠加

现在,如果我们添加一个TickerMode(由VisibilityNavigator等小部件隐式完成),我们可以暂停动画,从而停止不必要的刷新:

Opacity(
  opacity: 0,
  child: TickerMode(
    enabled: false,
    child: CircularProgressIndicator(),
  ),
),
Run Code Online (Sandbox Code Playgroud)

静音