我对视图类的forceLayout(), requestLayout()和invalidate()方法的角色有点困惑。
什么时候叫他们?
我对视图类的forceLayout(), requestLayout()和invalidate()方法的角色有点困惑。
什么时候叫他们?
当前回答
关于forceLayout()这个答案是不正确的。
正如你在forceLayout()的代码中看到的,它只是将视图标记为“需要重新布局”,但它既不计划也不触发该重新布局。重布局将不会发生,直到将来的某个时候,视图的父视图因为其他原因被布局。
在使用forceLayout()和requestLayout()时,还有一个更大的问题:
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.
我认为forceLayout()(以及它如何影响requestLayout()的实现是坏的,你不应该在你的代码中使用该函数。
其他回答
为了更好地理解François BOURLIEUX和Dalvik提供的答案,我建议你看看Arpit Mathur的这张很棒的视图生命周期图:
invalidate()——> onDraw()从UI线程
postInvalidate()——> onDraw()从后台线程
requestLayout()——> onMeasure() and onLayout() and NOT Necessarily onDraw()
重要提示:调用此方法不会影响被调用类的子类。
forceLayout()——> onMeasure()和onLayout()只是如果直接父调用requestLayout()。
关于forceLayout()这个答案是不正确的。
正如你在forceLayout()的代码中看到的,它只是将视图标记为“需要重新布局”,但它既不计划也不触发该重新布局。重布局将不会发生,直到将来的某个时候,视图的父视图因为其他原因被布局。
在使用forceLayout()和requestLayout()时,还有一个更大的问题:
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.
我认为forceLayout()(以及它如何影响requestLayout()的实现是坏的,你不应该在你的代码中使用该函数。
你在你想要重绘的视图上使用invalidate(),它将使它的onDraw(Canvas c)被调用,requestLayout()将使整个布局渲染(测量阶段和定位阶段)再次运行。如果你在运行时改变子视图的大小,你应该使用它,但只有在特定的情况下,比如来自父视图的约束(我的意思是父视图的高度或宽度是WRAP_CONTENT,所以匹配测量子视图之前,他们可以再次包装他们)
这里你可以找到一些回应: http://developer.android.com/guide/topics/ui/how-android-draws.html
对我来说,调用invalidate()只会刷新视图,调用requestLayout()会刷新视图,并在屏幕上计算视图的大小。