Skip to content
阅读进度

measure 和 layout 的区别?getWidth 与 getMeasuredWidth 呢? ​

返回 View 与显示链路 目录

标准回答 ​

measure 得到测量宽高;layout 由父容器安排孩子的 left、top、right、bottom,确定最终边界。getMeasuredWidth 读取测量结果,getWidth 则是最终布局边界的 right 减 left。

正常布局中,两者常常相同,但含义不同。孩子测量完、尚未布局时,可能已经有 measuredWidth,却还没有本轮最终 width。自定义父容器也可能用与测量结果不同的边界放置孩子,因此不能认为这两个值永远相等。

ViewGroup 通常在 onMeasure 测量孩子,在 onLayout 调用孩子的 layout 安排位置。孩子的 left 和 top 是相对父容器的布局位置,不是它在整个屏幕上的绝对坐标。translationX / translationY 还可能改变视觉位置,而不改写原来的 left / top。

关键机制 ​

  • 自定义 ViewGroup 需要同时处理测量与排布,不能只给自己设置一个大小。
  • getX 通常体现 left 与 translationX 的组合;获取屏幕位置应使用对应坐标 API。
  • padding 影响自身内容区;margin 是父容器排布孩子时遵循的外部间距,具体支持由 LayoutParams 决定。

通俗例子 ​

按钮 layout 到 left=20、right=120 时宽度是 100。再设置 translationX=30,视觉上向右移动,但它的布局 left 仍然可以是 20。

追问与回答 ​

为什么 getWidth 在 onCreate 里经常为 0? ​

onCreate 中通常只是创建并设置了内容,窗口的后续布局还没有完成。此时读到的 0 不代表 XML 配错了。依赖最终尺寸的计算应该放到布局完成的回调,或者自定义 View 的 onSizeChanged 等合适阶段。

易混淆点 ​

控件尺寸与坐标取决于所处阶段和坐标系。截图上的位置不一定等于 getLeft 返回值。

参考资料 ​

内容来源 ​

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