是什么触发视图的measure()被调用

发布于 2024-11-27 17:49:13 字数 562 浏览 0 评论 0原文

在我的应用程序中,我的视图的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的呼吸 2024-12-04 17:49:13

为了触发自定义视图的测量传递,您必须调用 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();
}

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:

/**
 * 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();
}
等风也等你 2024-12-04 17:49:13

好吧,如果您要更改视图的内容,它最终必须调用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文