First thing! I do know about ViewTreeObserver.onGlobalLayoutListener
.
What made me ask this question is the following notice on Android developer documentation website:
The snippet below does the following:
- Gets the parent view and posts a Runnable on the UI thread. This ensures that the parent lays out its children before calling the getHitRect() method. The getHitRect() method gets the child's hit rectangle (touchable area) in the parent's coordinates.
Snippet itself is:
parentView.post(new Runnable() { // Post in the parent's message queue to make sure the parent // lays out its children before you call getHitRect() @Override public void run() { /// do UI stuff } });
(you can look at the full article)
So is this a wrong statement or is it true? I am asking because posting a runnable seems easier and more convenient compared to doing all that register-listener/handle-event/unregister-listener dance with ViewTreeObserver :)
UPDATE: One more question to bring clarity to the whole subject: If all this is nice and Runnable can actually be posted instead of using a global layout listener, then why do we have this ViewTreeObserver.onGlobalLayoutListener
mechanism at all? When is it better to use it rather than posting a Runnable and what the difference is between this methods?
I like the question too. It forced me to dig into Android source code once again. I believe this works because post()
gets called after setContentView()
.
Method setContentView()
ends up in calling ViewGroup.addView()
of the top view, and addView()
call always triggers requestLayout()
. In turn, requestLayout()
posts a task to the main thread to be executed later. This task will execute measure and layout on the view hierarchy. Now if you post another task it will be put into the queue after layout task and, as the result, always executed after measure and layout happen. Thus you will always have valid sizes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With