接触Android一段时间后,便对LayoutInflater有很多的疑问,因为它实在有太多表达方式了。各种表达方式适合在不同的地方使用,接下来,我们来总结一下。

1.它有什么作用?

   我们经常使用setContentView(R.layout.xxx)载入我们需要的layout。从而用findViewById()找出里面的控件,但是如果我们需要载入其它layout呢。你可以简单地认为 LayoutInflater就是获得layout下的xml资源。

2.LayoutInflater的基本用法

第一种写法如下:

LayoutInflater layoutInflater = LayoutInflater.from(context); 

第二种写法如下:

LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

第三种写法如下:

LayoutInflater inflater=this.getLayoutInflater();

其实第一种就是第二种的简单写法,只是Android给我们做了一下封装而已。

第一种和第二种在一般情况下都可以用,但第三种必须在继承Activity的类中使用。

如:

public class MainActivity extends Activity {

    @Override    

    public void onCreate(Bundle savedInstanceState) {   

      super.onCreate(savedInstanceState);       

     setContentView(R.layout.activity_main);       

     LayoutInflater inflater=this.getLayoutInflater(); 

}   

得到了LayoutInflater的实例之后就可以调用它的inflate()方法来加载布局了。

inflate(int resource, ViewGroup root, boolean attachToRoot) 

解释一下这三个参数:

1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。

2. 如果root不为null,attachToRoot设为true,则会在加载的布局文件的最外层再嵌套一层root布局。

3. 如果root不为null,attachToRoot设为false,则root参数失去作用。

4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

这里有几种做法:

第一种:

LayoutInflater inflater=LayoutInflater.from(this);

RelativeLayout ff=(RelativeLayout)findViewById(R.id.ff);   //获得id=ff的RelativeLayout布局。

View item= inflater.inflate(R.layout.item, null);          //获得R.layout.item资源

ff.addView(item);                       //把它添加至RelativeLayout布局ff中。

 

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/ff"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

</RelativeLayout>

 

item.xml

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    

android:layout_width="match_parent"    

android:layout_height="match_parent"    

android:orientation="vertical" >

 <TextView        

android:layout_width="wrap_content"        

android:layout_height="wrap_content"        

android:text="111"          /> 

</LinearLayout>

效果图:

第二种:

LayoutInflater inflater=LayoutInflater.from(this);

RelativeLayout ff=(RelativeLayout)findViewById(R.id.ff);   //获得id=ff的RelativeLayout布局。

View item= inflater.inflate(R.layout.item, ff,true);       //获得R.layout.item资源,把它添加至RelativeLayout布局ff中。

 

跟第一种对比后,可以发现inflate(int resource, ViewGroup root, boolean attachToRoot) 中的 ViewGroup root,实际上是调用了root.addView();

而此时,我们传入的是ff,即root=ff,root.addView()==>ff.addView(item);

如果第一种和第二种的效果是一样的。

我们从源代码上分析:

  if (root != null && attachToRoot) {
          root.addView(temp, params);
       } 

以上是LayoutInflater.class中的一段代码。从这段中就可以知道ViewGroup root, boolean attachToRoot这些参数有什么作用。

必须说的是ViewGroup root是“容器类”。也就是说传进去的值的类型一定要是 RelativeLayout、LinearLayout、 FrameLayout等“容器类”,像上面ff就是 RelativeLayout,所以才可以传进去。因为有些人分不清什么是ViewGroup,什么是View。    

第三种:
View item=View.inflate(Context context, int resource, ViewGroup root)

这一种比较简单,不用写LayoutInflater inflater=LayoutInflater.from(this) 之类的,就可以直接用了。ViewGroup root跟上面一样。

代码如:View item=View.inflate(this, R.layout.item, null);