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);
}
}
效果与前面一致。