性能:如何防止requestLayout()布局整个层次结构

时间:2013-01-31 11:19:01

标签: android performance layout

我有一个非常复杂的android应用程序。尽可能扁平化视图层次结构,但我仍然在应用程序中滞后。例如,有一个菜单,其条目通过将其高度设置为ValueAnimator来折叠/展开。通常,动画在第一次运行时会有一点延迟,并且在第一次通过后会平滑。

我注意到当我在菜单项上调用“requestLayout()”时,Android似乎会执行布局传递和多次测量 - 遍历整个层次结构。

  • 既然我知道虽然菜单项(视图)改变了高度,但菜单(视图)本身没有,是否有某种方法可以告诉应用程序?
  • 我可以以某种方式执行第一次看似落后的通行证,以便在应用程序启动后而不是在第一次触摸输入时发生吗?

这是我正在做的动画的草图:

enter image description here

2 个答案:

答案 0 :(得分:6)

我不确定为什么动画会触发布局,但我会抽象地回答你的问题。

如果你在动画中调用requestLayout(直接或间接),那你就是错误的。

requestLayout,为了正确性和安全性,在视图层次结构上执行完整视图遍历b / c概念上更改视图层次结构中节点的边界框可能导致任何其他节点的边界发生更改。并非总是如此,但总的来说它可能,这就是为什么requestLayout是一个完整的遍历。

所有这些只是另一种说法,即requestLayout将从你的16.6毫秒帧时间消耗时间并使你的动画不稳定。这对于具有许多RelativeLayouts的深层和复杂层次结构尤其糟糕,它们在内部每个层次执行两次传递(因此可能导致子树上的指数传递)

现在,如果要在维度中更改动画,请在硬件层中使用setScale。在动画结束时,请快速调用requestlayout并破坏图层(以释放内存)。

因为它是一个图层,在动画中反复调用setScale会导致GPU上的纹理发生变化,从而完全绕过视图层次结构的遍历机制。这应该使它变得光滑。

答案 1 :(得分:0)

你的问题看起来像我的:Only relayout children and not all the tree

首先,您可以尝试避免视图的复杂视图层次结构。如果可能,请在不依赖于其他视图的视图上展开视图。

执行动画时,请避免任何布局请求。如果布局请求处于待处理状态,请延迟启动动画。

如果可能,请使用硬件层进行动画制作(可能Android默认使用ValueAnimator