Loading

LayoutInflater类的作用与用法

在实际开发会用到LayoutInflater这个类,它的作用类似于 findViewById()。
LayoutInflater是用来找layout下xml布局文件,并且实例化,而findViewById()是找具体xml下的具体 widget控件(如:Button,TextView等)。
对于一个没有被载入或者想要动态加载的界面,都需要使用LayoutInflater.inflate()来载入。

什么叫做动态加载的界面呢?
在应用中有时候需要通过某些点击效果动态地添加布局,而不是直接加载完整的xml布局文件,就需要动态载入。
http://blog.csdn.net/u013227064/article/details/51108732

接下来看一下LayoutInflater的用法。
inflate方法有三个参数(int resource, ViewGroup root, boolean attachToRoot)。
resource:需要加载布局文件的id,意思是需要将这个布局文件中加载到Activity中来操作。

root:需要附加到resource资源文件的根控件,什么意思呢,就是inflate()会返回一个View对象,如果第三个参数attachToRoot为true,就将这个root作为根对象返回,否则仅仅将这个root对象的LayoutParams属性附加到resource对象的根布局对象上,也就是布局文件resource的最外层的View上,比如是一个LinearLayout或者其它的Layout对象。

attachToRoot:是否将root附加到布局文件的根视图上
很难理解的话,我们来看下面一段代码。
我的activity_main布局如下

<?xml versio`这里写代码片`n="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/qwe"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

</LinearLayout>

我还有一个linearlayout如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/asd"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:background="@color/colorPrimaryDark"
    android:gravity="center"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是一个按钮"/>
</LinearLayout>

我现在想把这个linearlayout布局添加到我的activity_main中去,可以这么做。

package com.example.inflatertest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.qwe);
        LayoutInflater inflater = LayoutInflater.from(this);
        inflater.inflate(R.layout.linearlayout, ll,true);
    }
}

效果如图
这里写图片描述
inflate方法返回的是一个view,而我并没有添加这个返回的view就已经将linearlayout添加进来了。因为我的第三个参数设置为true,表示将第一个参数所指定的布局添加到第二个参数的View中。
如果多写那么一行代码。

package com.example.inflatertest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.qwe);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view=inflater.inflate(R.layout.linearlayout, ll,true);
        ll.addView(view);
    }
}

会抛出如下错误:
这里写图片描述
原因就是因为当第三个参数为true时,会自动将第一个参数所指定的View添加到第二个参数所指定的View中。

下面我们再来看看当第三个参数attachToRoot为false时的情况。
当attachToRoot为false时,表示不将第一个参数所指定的View添加到第二个参数root中去。因为我们想要添加布局可以把第三个参数设为true,那我们为什么这里要设为false呢?我们在设置控件的时候,都会设置layout_width和layout_height,这两个属性表示的是在容器里的大小,当然也意味着,这两个属性必须要在容器里才有意义,否则没有意义。

这就意味着如果我直接将linearlayout加载进来而不给它指定一个父布局,则inflate布局的根节点的layout_width和layout_height属性将会失效(因为这个时候linearlayout将不处于任何容器中,那么它的根节点的宽高自然会失效)。
如果我想让linearlayout的根节点有效,又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。
还是那两个布局,这次我想添加该怎么办呢?

package com.example.inflatertest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout) findViewById(R.id.qwe);
        LayoutInflater inflater = LayoutInflater.from(this);
        View view=inflater.inflate(R.layout.linearlayout, ll,false);
        ll.addView(view);
    }
}

效果与前面一致。

posted @ 2017-10-29 11:10  Xianhao  阅读(62)  评论(0编辑  收藏  举报