LayoutInflater.inflate详解

介绍常见inflate方法

在日常开发中经常会用到通过资源id去获取view的场景,我们通常有四种方式去获取view,分别是以下四种:

//1,通过系统服务获取布局加载器
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View view = inflater.inflate(resource,root,attachToRoot);

//2,通过activity中的getLayoutInflater()方法
View view = getLayoutInflater().inflate(resource,root,attachToRoot);

//3,通过View的静态inflate()方法
View view = View.inflate(resource,root,attachToRoot);

//4,通过LayoutInflater的inflate()方法
View view = LayoutInflater.from(this).inflate(resource,root,attachToRoot);

通过对上述方法的源码的分析,很容易看出来这些方法都是最终调用了方式1,获取系统布局加载器的方式,来进行获取`View`。

这里我列举的并没有`inflate(int resource, ViewGroup root)`这个重载方法,是因为他们最终都会到调用为`inflate(int resource, ViewGroup root, boolean attachToRoot)`方法,如下:

 public View inflate(int resource, ViewGroup root) {
        return inflate(resource, root, root != null);
 }

 public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
        if (DEBUG) System.out.println("INFLATING from resource: " + resource);
        XmlResourceParser parser = getContext().getResources().getLayout(resource);
        try {
            return inflate(parser, root, attachToRoot);
        } finally {
            parser.close();
        }
 }

这里要说明一下,其实最终要调用的是`inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)`方法,只不过这里把布局资源解析为了XmlPull解析器,这里就不针对`XmlPullParser`进行研究了。

针对传入的参数不同进行分析

通过对`inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)`方法的源码进行解读,`XmlPullParser parser`是对传入`int resource`的xml解析器,不用去主要考虑,那就需要考虑传入`ViewGroup root, boolean attachToRoot`的值不同,会出现什么结果呢?

源码中有几个重要的代码块:

if (root != null) {
if (DEBUG) {
System.out.println("Creating params from root: " +
                                    root);
}
// 如果root不等于null,获取它的LayoutParams
  params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
//attachToRoot等于false,把root的LayoutParams属性给temp
temp.setLayoutParams(params);
}
}
//attachToRoot等于true,将temp加入到root这个viewGroup中
if (root != null && attachToRoot) {
root.addView(temp, params);
}

// root等于null,attachToRoot等于false,直接把temp赋值给返回结果
if (root == null || !attachToRoot) {
  result = temp;
}

根据不同的传值进行实现

两个布局文件,一个作为root,一个作为我们的要获取的view

activity_my.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

view.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:background="@color/blue">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello inflate"
        android:textColor="@android:color/white" />

</LinearLayout>

1,rootView等于null,attachToRoot等于false

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    view = getLayoutInflater().inflate(R.layout.view, null, false);
    setContentView(view);
}

本身root为null,就不会去获取view的LayoutParams,直接走`result = temp;`返回result,此时result等于view

为什么会充满屏幕呢,因为当把view设置到activity的视图时,系统会取当前window的LayoutParm作为view的LayoutParm

2,rootView等于null,attachToRoot等于true

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
    view = getLayoutInflater().inflate(R.layout.view, null, true);
    setContentView(view);
}

root等于null,依然走`result = temp;`,此时result等于view

为什么会充满屏幕呢,因为当把view设置到activity的视图时,系统会取当前window的LayoutParm作为view的LayoutParm

3,rootView不等于null,attachToRoot等于false

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView = getLayoutInflater().inflate(R.layout.activity_my, null);
    view = getLayoutInflater().inflate(R.layout.view,(ViewGroup)rootView,false);
    setContentView(view);
}

root不等于null,attachToRoot等于false,会走取view的LayoutParams并且赋值给temp,再走`result = temp;`,此时result等于view

为什么会充满屏幕呢,因为当把view设置到activity的视图时,系统会取当前window的LayoutParm作为view的LayoutParm

4,rootView不等于null,attachToRoot等于true

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rootView = getLayoutInflater().inflate(R.layout.activity_my, null);
    view = getLayoutInflater().inflate(R.layout.view,(ViewGroup)rootView,true);
    setContentView(view);
}

rootView不等于null,attachToRoot等于true,会首先获取view的Params,再走`root.addView(temp, params)`,也就是,把view先放入的root这个ViewGroup中,再返回result,因为初始化的时候result就等于root,此时返回的就是包含有子View的root。

这里因为root的布局为RelativeLayout,我们把view加入到root中,view本身保留了自有的LayoutParm

最后我要吐槽,为什么csdn不支持markdown,我都是先用Mou写好的,贴过来竟然要自己重新排版。。。

时间: 2024-10-29 19:10:19

LayoutInflater.inflate详解的相关文章

android LayoutInflater.inflate详解

LayoutInflater概述 从XML文件中实例化一个布局成对应的View类, 它从来不会直接使用, 而是使用getLayoutInflater()或者getSystemService(String)来获得一个对应当前context的标准LayoutInflater 实例. 例如: 1 2 3 LayoutInflater inflater = (LayoutInflater)context.getSystemService       (Context.LAYOUT_INFLATER_SE

LayoutInflater类详解

http://www.cnblogs.com/top5/archive/2012/05/04/2482328.html 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于 findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化:而 findViewById()是找xml布局文件下的具体widget控件(如Button.TextView等). 具体作用: 1.对于一个没有被载入或者想要动态载入的界面,

[Android]LayoutInflater的inflate方法半详解

好久没写博客,作为一名刚加入android阵营的android狗,发心得刷人气来了!!!(半详解是因为说详不那么详,说不详也稍微有点详..)哈哈~~..咳..咳.. 一.Activity中的setContentView 对于刚开始学Android的新手来说,在Activity中加载布局文件的方法是在onCreate()回调方法中直接调用setContentView()方法,如: @Override protected void onCreate(Bundle savedInstanceState

LayoutInflater的inflate函数用法详解

LayoutInflater的inflate函数用法详解 LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 获取LayoutInflater的方法有如下三种: ? LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.main, nul

转载《 LayoutInflater 的inflate函数用法详解》

LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 获取LayoutInflater的方法有如下三种: LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.main, null); LayoutInflater inflater = L

【android】LayoutInflater.inflate方法的详解及xml根元素的布局参数不起作用的问题

一.首先看带三个参数的inflate方法: public View inflate (int resource, ViewGroup root, boolean attachToRoot) 1.如果root不为null,且attachToRoot为TRUE,则会在加载的布局文件的最外层再嵌套一层root布局,这时候xml根元素的布局参数当然会起作用. 2.如果root不为null,且attachToRoot为false,则不会在加载的布局文件的最外层再嵌套一层root布局,这个root只会用于为

Android LayoutInflater 详解

Android LayoutInflater 详解 简介: 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById(). 不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化:而findViewById()是找xml布局文件下的具体widget控件(如Button,TextView等等). 使用场景: ①对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflater()来

安卓学习笔记:转Android LayoutInflater详解

Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化:而 findViewById()是找xml布局文件下的具体widget控件(如Button.TextView等). 具体作用: 1.对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入: 2

LinearLayout详解三:LayoutInflater创建View过程分析

项目人力资源管理主要有以下几个过程: 编制人力资源管理计划 组建项目团队 建设项目团队 项目团队管理 编制人力资源管理计划 根据什么来编? 直观点就是你要干什么事?干这些事有哪些制约? 这个说起来好像和没说一样,但就我自己做的一些项目来说,有以下困难: 1> 项目前期需求是不具体不明确的 这样直接导致你做项目计划时WBS也是不明确的,进而你细化不了活动,自然你也没法 明确活动需要什么样的人. 这个时候怎么办? 就我个人而言,有2种员工很喜欢: 1> 数学思维强的, 注意不是会做高数题,是指给你