是什么触发视图的measure()被调用
在我的应用程序中,我的视图的 onMeasure() 覆盖之一有无限循环。从 onMeasure 中的断点开始调试源代码,我能够沿着堆栈跟踪一直跟踪到 PhoneWindow$DecorView 的measure()(我的视图层次结构中最顶层的类),它由 ViewRoot 调用.performTraversals()。现在,如果我继续跨过去,我最终会通过 Looper.loop() 类中的消息再次调用 PhoneWindow$DecorView 的measure()。我猜想有些东西已经排队了一条需要重新测量的消息,比如无效。
我的问题是,什么触发器需要在视图上发生测量调用?
根据我对布局/测量/绘制过程的理解,只有在特定视图上调用 invalidate() 方法时才会发生这种情况,并且该方法将向下渗透并为该无效视图执行布局/测量/绘制过程,并且所有视图都将被调用。它的孩子。我会假设我的视图层次结构中最顶层的视图不知何故变得无效。
但是,我已经明确地在每个无效调用上放置了一个断点,并且不会以某种无限的方式调用无效。所以我认为情况并非如此。还有其他方法可以触发测量通过吗?内部可能有什么东西触发了这个吗?在看到没有什么是无限无效之后,我有点失去了想法。
In my application I have an infinite loop on one of my View's onMeasure() overrides. Debugging the source code starting from a break point in my onMeasure, I am able to trace myself all the way up the stack trace up to the PhoneWindow$DecorView's measure() (top most class in my View Hierarchy), which gets called by ViewRoot.performTraversals(). Now from here if I keep stepping over, I eventually get the PhoneWindow$DecorView's measure() called again by a message in the Looper.loop() class. I'm guessing something has queued up a message that it needs to remeasure, like an invalidate.
My question is, what triggers that a measure call needs to occur on a View?
From my understanding of the layout/measure/draw process, this will only occur when the invalidate() method is called on a specific view, and that will trickle down and perform a layout/measure/draw pass for that view invalidated and all of its children. I would assume that somehow my top most View in my View Hierarchy is getting invalidated.
However, I've explicitly put a break point on every single invalidate call I have, and am not calling invalidate in some infinite manner. So I do not think that is the case. Is there another way to trigger a measure pass? Could something internally be triggering this? I'm kind of out of ideas after seeing that nothing is infinity invalidating.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了触发自定义视图的测量传递,您必须调用 requestLayout() 方法。
例如,如果您正在实现一个扩展 View 的自定义视图,并且其行为类似于 TextView,则可以编写如下 setText 方法:
In order to trigger a measure pass for a custom View you must call the requestLayout() method.
For example, if you are implementing a custom view that extends View and it will behave like a TextView, you could write a setText method like this:
好吧,如果您要更改视图的内容,它最终必须调用 invalidate()。例如,您有一个 TextView,其中包含名为“Text 1”的文本。现在,您将同一 TextView 的文本更改为“Text 2”。这里同样会调用 invalidate 。
所以基本上,当视图上发生某些变化时,您通常会期望调用 invalidate 方法,以及对measure() 的相应调用。
例如,查看 TextView 的源代码。
http://www.google.com/codesearch#uX1GffpyOZk/core/java/android/widget/TextView.java&q=TextView%20package:android&type=cs
统计数量无效调用。有不少。
Well, If you are changing a View's content, it will eventually have to call invalidate(). For example, you have a TextView with a text called "Text 1". Now, you change the text of the same TextView to "Text 2". Here aslo, invalidate will be called.
So basically, when something changes on the view, more often than not, you would expect the invalidate method to be called, and a corresponding call to the measure().
Look at the source code for TextView, for example.
http://www.google.com/codesearch#uX1GffpyOZk/core/java/android/widget/TextView.java&q=TextView%20package:android&type=cs
Count the number of invalidate calls. There are quite a few.