活动开始时的动画跳跃问题

10
我正在为我的Android应用程序制作自定义视图的动画效果。我已经通过属性动画和在onAnimationUpdate()回调中对View调用invalidate()来完成了这个过程,就像https://developer.android.com/guide/topics/graphics/prop-animation.html所述:

根据您要动画化的属性或对象,您可能需要在View上调用invalidate()方法,以强制屏幕使用更新后的动画值重新绘制自身。您可以在onAnimationUpdate()回调中执行此操作。

我的问题是当这些动画在一次新启动的Activity开始时运行时,它们在开头跳帧,导致它们明显地跳跃。我已经尝试过:
  1. 在Activity的onCreate()方法中立即启动动画。
  2. 使用Activity根视图的ViewTreeObserver,在OnGlobalLayout()回调上启动动画。

我选择了后者,因为我认为动画可能在布局完成之前被调用,但结果是相同的。

通过日志,我确定onAnimationUpdate()回调在整个动画过程中都被一致地调用(即从开始到结束,每10-20毫秒左右)。onAnimationUpdate()只是调用invalidate(),这应该强制View立即重绘自身(但文档仅声称这会在“将来的某个时间点”发生)。这似乎正是问题所在:onDraw()在一开始只被调用一两次,然后大约250毫秒不被调用。之后,它恢复每10-20毫秒被调用一次,就像整个时间段一样。但那段时间会导致动画明显卡顿。
请注意,这个问题只发生在 Activity 开始时。如果我在动画开始前设置 300 毫秒的延迟,那么整个动画就会顺畅运行。但我不喜欢这种解决方案,因为它很 hacky。似乎问题在于 onDraw() 在 Activity 开始时调用 invalidate() 时并不会立即被调用。但是,我无法弄清楚为什么会出现这种情况,是什么阻止了 onDraw() 的调用,也不知道如何修复。
我只找到了这个 StackOverFlow 帖子:Activity 开始时动画跳帧,其中发布者遇到了完全相同的问题。基本代码已经在帖子中给出,并且视频清晰地展示了问题。我也可以发布我的代码,但我认为这个问题出现在最基本的测试应用程序中,说明还有其他问题。
2个回答

6

由于没有代码附加,我假设你的活动有一些过渡动画。如果是这种情况,可能会导致问题。因为有两个动画同时运行。禁用转换并尝试。

startActivity(intent);
getActivity().overridePendingTransition(0, 0); 

1
我没有自定义转场动画,但默认情况下有一个。按照建议禁用转场动画确实修复了动画问题。然而,由于这很突兀,我找到了以下Activity回调:onEnterAnimationComplete()。官方在那里解释了问题:“活动在其窗口动画期间无法绘制。”从该回调开始我的动画可以解决这个问题。 - asaini007
@asaini007 这个方法是存在的,但是只能在API 21及以上版本中使用。顺便说一下,它并不总是有效。 - Xavier.S

2
听起来像是你的绘制循环UI线程被饿死了。
我建议使用traceview来确保没有任何方法阻塞了你的绘制调用。http://tools.android.com/tips/traceview 这应该可以帮助你确定在onDraw方法之外被调用的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接