【Android】LayoutInflater 控件实例化的桥梁类

角色

我们知道 Android 的布局主要有两种来源:

  1. 代码创建 :直接 new TextView(context) 等方式构建。
  2. XML 创建 :在 res/layout 下定义 .xml 文件,然后通过 setContentView(R.layout.xxx)LayoutInflater 来加载。

LayoutInflater 就是桥梁,它的核心工作是:

  • 读取 XML 布局文件。
  • 解析节点(如 LinearLayout, TextView)。
  • 使用反射调用构造方法生成对应的 View。
  • 处理属性(如 android:layout_widthandroid:text)。
  • 组装成 View 树,返回根节点 View 实例。

调用链

常见的调用方式有三种:

在 Activity 中

java 复制代码
setContentView(R.layout.activity_main);

实际上内部会走到:

java 复制代码
LayoutInflater.from(this).inflate(R.layout.activity_main, getWindow().getDecorView(), true);

手动调用

java 复制代码
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item_view, parent, false);

在 Adapter 中

比如 RecyclerView 的 onCreateViewHolder

java 复制代码
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_list, parent, false);
    return new MyViewHolder(itemView);
}

参数含义

java 复制代码
inflate(int resource, ViewGroup root, boolean attachToRoot)
  • resource:要解析的布局文件 ID。
  • root:父容器。
  • attachToRoot:是否将生成的 View 立即添加到 root 中

关键点

  • 如果 root != nullattachToRoot = true,生成的 View 会自动加入 root。
  • 如果 attachToRoot = false,返回的 View 不会被加进去,但会用 root 的 LayoutParams
  • 如果 root = null,则只能拿到 View,本身没有 LayoutParams。

实际开发中,Adapter 场景常用 inflate(R.layout.xxx, parent, false),因为 Adapter 本身会先进行数据处理,再将处理过的 item 控件加入 root ,attachToRoot = false 避免重复 attach。


源码

inflate() 的核心片段:

java 复制代码
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
    View result = createViewFromTag(...); // 反射生成View
    ViewGroup.LayoutParams params = null;
​
    if (root != null) {
        params = root.generateLayoutParams(attrs); // 生成布局参数
        if (attachToRoot) {
            root.addView(result, params); // 加入父布局
        }
    }
​
    if (root != null && !attachToRoot) {
        result.setLayoutParams(params); // 仅赋值,不加入
    }
​
    return result;
}

可以看到核心流程就是: 反射创建 View → 解析属性 → 生成 LayoutParams → 根据 attachToRoot 决定是否加入父容器。

LayoutParams

LayoutParams 是用于父布局确定子控件在其内部的位置,大小或权重等属性的类,父布局下每个子控件都有自己的 LayoutParams 实例,由父布局创建和调用且只在父布局内生效,涉及 margin ,layout_gravity 等属性。

padding ,gravity 等子控件本身的属性在控件实例构造时完成,由 View 自己负责渲染加载和赋值,不涉及 LayoutParams 的父加载。


场景实践

  • Activity 场景 :直接用 setContentView
  • Fragment 场景inflater.inflate(R.layout.xxx, container, false)
  • Adapter 场景inflater.inflate(R.layout.item, parent, false)
  • 避免误用:attachToRoot 几乎只在特殊场景用 true。
  • 优化 :复杂布局中可借助 <merge>ViewStub 来减少层级,提升性能。

LayoutInflater 是 Android 界面系统的核心工具之一,看似只是 inflate 一行代码,实际上内部涉及反射、XML 解析、View 树构建等复杂逻辑。掌握它的参数意义和调用链,能写出高效可维护的 UI 代码。


问题

在一个新的XML布局文件中自己定义一个按钮,将这个按钮通过 LayoutInflater 膨胀到主页面 activity_main上,给出代码

所以答案如下

xml 复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
</LinearLayout>
xml 复制代码
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
​
</FrameLayout>
java 复制代码
LinearLayout container = findViewById(R.id.main);
container.addView(getLayoutInflater().inflate(R.layout.button_layout, container, false));
// or
getLayoutInflater().inflate(R.layout.button_layout, container, true);
相关推荐
CYRUS_STUDIO3 小时前
一步步带你移植 FART 到 Android 10,实现自动化脱壳
android·java·逆向
CYRUS_STUDIO3 小时前
FART 主动调用组件深度解析:破解 ART 下函数抽取壳的终极武器
android·java·逆向
蓝倾9766 小时前
淘宝/天猫店铺商品搜索API(taobao.item_search_shop)返回值详解
android·大数据·开发语言·python·开放api接口·淘宝开放平台
国家二级编程爱好者6 小时前
Android开机广播是有序还是无序?广播耗时原因是什么?
android
猿小蔡-Cool6 小时前
Robolectric如何启动一个Activity
android·单元测试·rebolectric
Industio_触觉智能6 小时前
瑞芯微RK3576开发板Android14三屏异显开发教程
android·开发板·瑞芯微·rk3576·多屏异显·rk3576j·三屏异显
AI视觉网奇8 小时前
android adb调试 鸿蒙
android
NRatel10 小时前
GooglePlay支付接入记录
android·游戏·unity·支付·googleplay
在下历飞雨10 小时前
为啥选了Kuikly?2025“液态玻璃时代“六大跨端框架横向对比
android·harmonyos