什么触发了View的measure()被调用

在我的应用程序中,我的View的onMeasure()覆盖之一有一个无限循环。 从我的onMeasure中的一个断点开始debugging源代码,我可以追踪自己一直到堆栈跟踪到PhoneWindow $ DecorView的measure()(我的View Hierarchy中最高级的类),ViewRoot .performTraversals()。 现在从这里开始,如果我继续走下去,我最终会通过Looper.loop()类中的消息再次调用PhoneWindow $ DecorView的measure()方法。 我在猜测,有些东西已经排好了需要重新测量的信息,就像一个无效的东西。

我的问题是,什么触发一个措施调用需要发生在一个视图?

根据我对布局/度量/绘制过程的理解,只有当在特定视图上调用invalidate()方法时,才会发生这种情况,并且会对该视图执行布局/测量/绘制过程,它的孩子。 我会认为,我的视图层次结构中最顶层的视图会失效。

但是,我已经明确地在每一个无效呼叫中都有一个断点,并且不会以某种无限的方式调用invalidate。 所以我不认为是这样。 是否有另一种方法来触发测量通行证? 内部可能会触发这个? 看到没有什么是无限无效的,我有种想法。

为了触发自定义视图的度量传递,您必须调用requestLayout()方法。 例如,如果您正在实现一个扩展View的自定义视图,它将像TextView一样工作,您可以编写一个像这样的setText方法:

 /** * Sets the string value of the view. * @param text the string to write */ public void setText(String text) { this.text = text; //calculates the new text width textWidth = mTextPaint.measureText(text); //force re-calculating the layout dimension and the redraw of the view requestLayout(); invalidate(); } 

那么,如果你正在改变视图的内容,它最终将不得不调用invalidate()。 例如,您有一个名为“文本1”的文本的TextView。 现在,将相同TextView的文本更改为“文本2”。 在这里,无效将被调用。

所以基本上,当视图上的内容发生变化时,通常会调用invalidate方法,并调用measure()。

例如,查看TextView的源代码。 http://www.google.com/codesearch#uX1GffpyOZk/core/java/android/widget/TextView.java&q=TextView%20package:android&type=cs

计算无效呼叫的数量。 有不less。