Android视图动画和硬件层

15

我正在尝试学习如何正确使用硬件层来实现视图动画。

我正在实现一个ViewGroup,使用户可以拖动子视图,然后在释放时将其动画到位置(就像ViewPager会停留在某个页面)。这篇文章指出,您应该仅在动画期间启用硬件层。

我的问题是,在启用硬件层之后,Android必须创建图层,这需要在Galaxy Nexus上花费70-100ms的时间。这意味着我无法在立即开始动画之前执行此操作,因为拖动和动画之间的延迟非常明显。出于同样的原因,我也无法在开始拖动时启用它。

现在,这种延迟仅在首次创建硬件层时存在,因此理想情况下,我希望它们在视图添加到布局时立即创建。有人向我指出了View.buildLayer(),但我不确定如何解决这个问题。

  • 实现此目标的正确方法是什么?
  • 我的ViewGroup中是否有任何可重写并在子视图上调用buildLayer()的方法?
  • 硬件层是否可以以某种方式无效化,导致另外70-100ms的延迟?我该如何处理?

什么是“硬件层”- GLSurfaceView? - Marcin Orlowski
我的意思是这个:https://developer.android.com/reference/android/view/View.html#LAYER_TYPE_HARDWARE - SimonVT
1个回答

13

如果缓存中没有图层,延迟就会发生。对于后续调用setLayerType(NONE)/setLayerType(HARDWARE),您不应该看到此延迟。您可以从onSizeChanged()中调用buildLayer()来强制构建一个图层并将其放入缓存中(调用setLayerType(NONE)将图层移动到缓存中)。

请注意,您所看到的延迟在很大程度上取决于您运行的设备。

之所以不应保持启用图层,是因为它会使每次视图更新时绘制工作量增加一倍。例如,如果您将ListView移动到图层中,然后滚动列表,滚动动画期间每个帧更新都会导致:(a) 列表重新绘制到图层中 (b) 将图层绘制在屏幕上。这非常浪费,并根据您的UI复杂性可能会导致性能问题。


1
好吧,我可能有点早庆祝了。我不小心把它留在了HARDWARE上。我可以看到它在onSizeChanged()之后创建图层,花费通常的70+毫秒。但是,当我需要对其进行动画处理时,第一次切换到HARDWARE时发生了同样的事情。 - SimonVT
1
只是为了明确,我会两次获得大的延迟。一次是在onSizeChanged()中从buildLayer()开始,另一次是第一次动画化视图时。之后,就没有延迟了。 - SimonVT

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