Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance: How to prevent requestLayout() from laying out entire hierarchy

I have a pretty complex android-application. Already flattened view-hierarchies as far as possible, but I still have lags in the application. For example there is a menu with entries that collapse/expand by having their height set by a ValueAnimator. Typically the animation runs with a bit of a lag the first time, and smooth after this first pass.

I noticed that when i call "requestLayout()" on the Menu-Item, Android seems to do a layout-pass and multiple measure-passes through the entire hierarchy.

  • Since i know that although the Menu-Item(View) changes height, the Menu(View) itself doesn't, is there some way to tell this to the application?
  • Can i somehow perform this first pass that seems to lag myself so that it occurs after application start-up and not at the first touch-input?

Here's a sketch of the animation I'm doing:

enter image description here

like image 865
Fabian Zeindl Avatar asked Jan 31 '13 11:01

Fabian Zeindl


1 Answers

I am not sure why a layout is being triggered in your animation but I am going to answer your question abstractly.

If you are calling requestLayout (either directly or indirectly) in your animation you are doing it WRONG.

requestLayout, for correctness and safety, does a full view traversal on the view hierarchy b/c conceptually changing bounding box of a node in the view hierarchy can result in change in the bounds of any other node. Not always the case but in general it could, thats why requestLayout is a full traversal.

All of this is just another way of saying requestLayout will eat away time from your 16.6 ms frame time slot and make your animation choppy. This is especially bad for deep and complex hierarchies with many RelativeLayouts which internally does two passes per level (thus potentially causing exponential passes on a subtree)

Now, if you want to animate change in dimension use setScale in a hardware layer. And at the end of the animation merrily call requestlayout and also destroy the layer (to free up memory).

Because its a layer, repeatedly calling setScale in your animation results in change of the texture on the GPU and as a result totally bypass the traversal mechanism of the view hierarchy. This should make it buttery smooth.

like image 93
numan salati Avatar answered Sep 28 '22 04:09

numan salati