我最初的问题是需要知道根View
的高度和宽度,以便我可以进行编程布局更改。出于我的目的,我不一定需要在onCreate()
期间确定此信息;对我来说,在根布局完成后以编程方式添加我的子View
就足够了,因此我很乐意使用 onWindowFocusChanged()
作为钩子来确定何时调用根View
的getWidth()
和getHeight()
将返回有效结果。
但是,我看到很多人问如何在onCreate()
期间确定根View
的大小。我猜人们想这样做是为了更好的用户体验 - 也许这样用户就不会看到分阶段构建的布局(如果有人能澄清原因,我将不胜感激)。现在,我经常看到的答案,例如这里的答案,是将Runnable
发布到onCreate()
中的根View
。在该Runnable
内部,我们执行 getWidth()
,等等。这样做的原因是因为,显然,发布到View
Runnable
的对象是在View
具有布局和/或附加到窗口时执行的。
这就引出了我的问题。在 View
的 API 文档中,它似乎没有描述这种行为。那么,谁能告诉我它在哪里定义和记录?或者,是检查来源的问题?Runnables
将保留在View
队列中并且仅在布局过程后的某个点处理,这是一个绝对且严格定义的功能吗?
进一步澄清:在阅读 Kerry 的回答并仔细思考后,我的基本问题可以澄清如下:在这里给出的答案以及此 CodeProject 条目中,我知道我们通过向View
发布Runnable
来解决根View's
维度在onCreate()
期间不可用的问题。正如 Kerry 指出的那样,保证是这条消息Runnable
在执行之前onCreate()
无法执行。我知道布局发生在onCreate
之后的某个点,但我目前仍然无法理解为什么当View
的尺寸已知时应该执行这个Runnable
。
我看了一下 View.post(Runnable)方法,在我看来,通过调用该方法,您只是将消息添加到UI线程队列中。唯一要"保证"的是,在调用 post(Runnable) 的方法完成后,Runnable 将在某个时间执行。这假设您正在从 UI 线程调用 post(Runnable),但正如文档所说:
仅当此视图附加到窗口时,才能从 UI 线程外部调用此方法。
我认为为了确保您的根视图和子视图都有大小,您需要从子 onSizeChanged() 方法调用 post(Runnable),因为如果子视图有大小,我认为随之而来的是父视图,即根视图因此也必须有大小。
抱歉,如果这是一个有点漫无边际的答案。我有点理解你想要实现的目标,但不是100%确定。如果您想让我澄清任何事情,请告诉我。
就个人而言,每当我需要视图的大小时,我都会在 onSizeChanged() 中执行所有操作,我相信这是"正确"的处理方式,并且它一直有效。