Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is requestLayout being called directly after invalidate

I'm learning about custom views and wanted to learn about invalidate() and requestLayout().

Please refer to this answer and its diagram:

https://stackoverflow.com/a/25846243/4243687

invalidate() tells Android that the state of the view has changed and needs to be re-drawn.

requestLayout() means the size of the view may have changed and needs to be remeasured, and then re-drawn.

invalidate() will invoke dispatchDraw(), draw(), and onDraw() hence it re-renders the view.

requestLayout() on the other hand does pretty much everything from measuring to re-rendering again.

Why do so many of the examples out there (even the TextView source code) call invalidate() and then requestLayout() right on the next line?

like image 965
Ersen Osman Avatar asked Feb 08 '16 21:02

Ersen Osman


People also ask

What is requestLayout?

If something about your view changes that will affect the size, then you should call requestLayout() . This will trigger onMeasure and onLayout not only for this view but all the way up the line for the parent views.

What is invalidate in Android?

Generally, invalidate() means 'redraw on screen' and results to a call of the view's onDraw() method. So if something changes and it needs to be reflected on screen, you need to call invalidate() .


3 Answers

invalidate() is used specifically for redrawing the content of your view. The redraw does not happen synchronously. Instead, it flags the region of your view as invalid so that it will be redrawn during the next render cycle.

requestLayout() should be used when something within it has possibly changed its dimensions. In this case, the parent view and all other parents up the view hierarchy will need to readjust themselves via a layout pass.

If you are not doing anything to your view that would change its size, then you do not have to call requestLayout().

If you go back and look at the places in the code for TextView where requestLayout() is being called, it will be on methods where the view's bounds will be affected. For example, setPadding(), setTypeface(), setCompoundDrawables(), etc.

So, when requestLayout() is called, it should be paired with a call to invalidate to ensure that the entire view is redrawn.

like image 102
Michael Krause Avatar answered Oct 18 '22 00:10

Michael Krause


After seeing the following diagram, I was under the impression that calling requestLayout() would eventually result in an onDraw.

enter image description here

Therefore, there would be no need to call these together because it would be redundant.

invalidate();
requestLayout();

However, it turns out that that diagram is misleading. Some views might in fact invalidate themselves when there is a layout change, but this is not a certainty. Calling requestLayout() is not guaranteed to result in onDraw being called.

My source (thanks to this comment) is the Romain Guy (who is an Android engineer at Google):

requestLayout() itself does not lead to a draw pass but some views might react to a Layout change by calling invalidate.

Therefore, to be certain a relayout will result in a redraw, then you should pair an invalidate() with the requestLayout(). (The opposite is not true, though. If you only need a redraw, then there is no need to call requestLayout(). A single invalidate() will do.)

like image 14
Suragch Avatar answered Oct 18 '22 01:10

Suragch


Relevant excerpt from the book Expert Android that answers the question:

Because the onClick event has caused the dimensions to change, our view needs to become bigger and take more space. How do we express that need to Android, Well, we request Layout(). This method goes up the chain, marking every view parent that it needs to be remeasured. When the final parent gets this request (the view root), the parent schedules a layout traversal. A layout traversal may or may not result in onDraw, although in this case it should. As a good programming practice, we also call invalidate() to ensure the drawing phase as well.

like image 2
a-hegde Avatar answered Oct 18 '22 00:10

a-hegde