Skip to content
阅读进度

inflate、addView、setContentView 是不是已经把界面画出来了? ​

返回 View 与显示链路 目录

标准回答 ​

不是。inflate 主要把 XML 布局创建成 View 对象树;addView 把一个 View 加入父容器;setContentView 把内容交给 Activity 的窗口。它们可以引发后续布局和绘制,但方法返回不代表内容已经显示。

inflate 的 root 参数还有生成正确 LayoutParams 的作用。attachToRoot 为 false 时,传入父容器仍然有价值:创建出来的根 View 可以获得适合该父容器的布局参数,只是暂时不附加。布局对象创建好后,只有进入有效窗口并经过必要遍历与渲染,用户才能看到。

这也是为什么 setContentView 后立即读取宽高可能是 0:对象存在与完成布局不是一回事。异步 Inflate 改变的是对象准备时机,不会自动完成窗口接入、UI 绑定和上屏。

关键机制 ​

  • RecyclerView 创建 item 时,常见写法是 inflate(layout, parent, false),随后由 RecyclerView 安排附加。
  • 把 root 写成 null,可能无法获得父容器需要的 LayoutParams;不是单纯少传一个无关参数。
  • 已经有 parent 的 View 不能随意再次附加到其他父容器,需要按正确生命周期和容器契约处理。

通俗例子 ​

XML 中写了 match_parent,只是布局意图。父容器尚未测量时,不能据此拿到最终像素宽度。

追问与回答 ​

为什么列表 item 不直接 attachToRoot=true? ​

因为 RecyclerView 负责管理 item 的附加、回收和复用。创建阶段先返回未附加的 View,让它生成正确布局参数即可。提前附加可能违反容器契约,或者在后续加入时出现已有父容器的错误。

易混淆点 ​

attachToRoot=false 不等于不需要父容器参数;inflate 完成也不等于 measure / layout 完成。

参考资料 ​

内容来源 ​

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