Skip to content
阅读进度

什么时候能拿到 View 宽高?onResume 时已经显示了吗? ​

返回 View 与显示链路 目录

标准回答 ​

View 完成本轮布局后,才能按布局结果可靠读取 getWidth / getHeight。Activity 的 onResume 表示生命周期进入相应状态,不承诺布局、GPU 渲染和屏幕展示都已经完成。

如果计算依赖控件尺寸,可以在自定义 View 的 onSizeChanged 中更新,或使用布局变化回调。OnPreDraw 在一次绘制开始前回调,适合在测量布局之后、绘制之前做轻量检查,但它仍然不是“已经上屏”的通知。

View.post 常被用于稍后执行,但它本质上是任务投递,不是专门证明本轮布局完成的契约。对于异步 Inflate、再次 requestLayout 或视图尚未接入窗口等情况,应直接观察需要的布局阶段。

如果目标是测首帧响应,尺寸大于 0 只能证明几何信息可用,onPreDraw 只能证明走到绘制前。真正的展示终点仍需要目标帧的显示证据。

关键机制 ​

  • OnLayoutChangeListener 可以观察布局边界变化;仅使用一次时及时移除,长期使用也要管理生命周期。
  • onSizeChanged 针对尺寸变化,适合缓存圆心、路径等几何信息,避免每次 onDraw 重算。
  • OnPreDraw 返回 false 会取消当前这次绘制;不要无意长期阻止页面出帧。

通俗例子 ​

异步布局回调在 onResume 之后才返回完全可能;这不是生命周期乱序,而是页面进入生命周期与内容准备好采用了不同进度。

追问与回答 ​

有没有简单的 Java 写法? ​

下面的回调读取下一次绘制前的尺寸,并立即移除自己。它适合做一次轻量的布局结果检查;不是上屏计时器,也不应在其中执行 IO。若 View 不再进入绘制阶段,回调也不会凭空执行。

易混淆点 ​

onWindowFocusChanged 和 IdleHandler 也不是通用的首帧实际展示证明。

参考资料 ​

内容来源 ​

用完整回答理解机制,用真实证据解释项目。