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

我有一个非常复杂的android应用程序。 尽可能地将视图层次化,但我仍然在应用程序中滞后。 例如,有一个菜单项可以通过由ValueAnimator设置高度来折叠/展开。 通常情况下,animation在第一次运行时有一点滞后,并且在第一次通过之后平滑。

我注意到,当我在Menu-Item上调用“requestLayout()”时,Android似乎做了布局传递和多个度量传递整个层次结构。

  • 因为我知道虽然菜单项(视图)改变高度,菜单(视图)本身没有,有没有办法告诉这个应用程序?
  • 我可以以某种方式执行这个第一遍,似乎滞后于自己,以便它在应用程序启动后发生,而不是在第一次触摸input?

这是我正在做的animation的草图:

在这里输入图像说明

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

我不知道为什么在animation中触发布局,但我会抽象地回答你的问题。

如果您在animation中调用requestLayout(直接或间接),那么就是错误的。

为了正确性和安全性,requestLayout在视图层次b / c上进行全视图遍历,从概念上改变视图层次中节点的边界框可以导致任何其他节点的边界发生变化。 并不总是这样,但一般情况下,它可以,这就是为什么requestLayout是一个完整的遍历。

所有这些只是requestLayout从16.6毫秒帧时隙中消除时间的另一种方式,使您的animation波涛汹涌。 这对于具有许多RelativeLayouts的深层复杂层次结构来说尤其糟糕,这些层次结构在内部会进行两个级别的遍历(因此可能会导致子树上的指数遍历)

现在,如果要在维度中animation更改,请在硬件层中使用setScale。 并在animation结束时愉快地调用requestlayout并且销毁图层(释放内存)。

因为它的一个图层,在animation中反复调用setScale会导致GPU纹理发生变化,从而完全绕过视图层次的遍历机制。 这应该使它奶油顺利。

你的问题看起来像我的: 只重新安置孩子,而不是所有的树

首先,您可以尝试避免视图的复杂视图层次结构。 如果可能的话,展开不依赖于另一个视图的观点。

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

如果可能的话,使用硬件层进行animation(也许Android默认使用ValueAnimator