I’m a bit confused about the roles of
invalidate() methods of the
When shall they be called?
invalidate() is done when you want to schedule a redraw of the view. It will result in
onDraw being called eventually (soon, but not immediately). An example of when a custom view would call it is when a text or background color property has changed.
The view will be redrawn but the size will not change.
If something about your view changes that will affect the size, then you should call
requestLayout(). This will trigger
onLayout not only for this view but all the way up the line for the parent views.
requestLayout() is not guaranteed to result in an
onDraw (contrary to what the diagram in the accepted answer implies), so it is usually combined with
An example of this is when a custom label has its text property changed. The label would change size and thus need to be remeasured and redrawn.
When there is a
requestLayout() that is called on a parent view group, it does not necessary need to remeasure and relayout its child views. However, if a child should be included in the remeasure and relayout, then you can call
forceLayout() on the child.
forceLayout() only works on a child if it occurs in conjunction with a
requestLayout() on its direct parent. Calling
forceLayout() by itself will have no effect since it does not trigger a
requestLayout() up the view tree.
Read this Q&A for a more detailed description of
Here you can find some response:
For me a call to
invalidate() only refreshes the view and a call to
requestLayout() refreshes the view and compute the size of the view on the screen.
you use invalidate() on a view that you want to redraw, it’ll make its onDraw(Canvas c) to invoked, and requestLayout() will make the whole layout rendering ( measurement phase and positioning phase) run again. You should use it if you are changing child view’s size on runtime but only in particular cases like constraints from the parent view(by that I mean that the parent height or width are WRAP_CONTENT and so match measure the children before they can wrap them again)
This answer is not correct about
As you can see in the code of
forceLayout() it merely marks the view as “needs a relayout” but it does neither schedule nor trigger that relayout. The relayout will not happen until at some point in the future the view’s parent was laid out for some other reason.
There is also a much bigger issue when using
Let’s say you’ve called
forceLayout() on a view. Now when calling
requestLayout() on a descendent of that view, Android will recursively call
requestLayout() on that descendent’s ancestors. The problem is that it will stop the recursion at the view on which you’ve called
forceLayout(). So the
requestLayout() call will never reach the view root and thus never schedule a layout pass. An entire subtree of the view hierarchy is waiting for a layout and calling
requestLayout() on any view of that subtree will not cause a layout. Only calling
requestLayout() on any view outside that subtree will break the spell.
I’d consider the implementation of
forceLayout() (and how it affects
requestLayout() to be broken and you should never use that function in your code.