接触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);