大家对LayoutInflater一定不陌生,它主要用于加载布局,在Fragment的onCreateView方法、ListView
Adapter的getView方法等许多地方都可以见到它的身影。今天主要聊聊LayoutInflater的用法以及加载布局的工作原理。
什么是LayoutInflater
LayoutInflater是一个用于将xml布局文件加载为View或者ViewGroup对象的工具,我们可以称之为布局加载器。
用法
获取LayoutInflater
首先要注意LayoutInflater本身是一个抽象类,我们不可以直接通过new的方式去获得它的实例,通常有下面三种方式:
第一种:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
第二种:
LayoutInflater inflater = LayoutInflater.from(context);
第三种:
在Activity内部调用getLayoutInflater()方法
看看后面两种方法的实现:
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
在Activity内部调用getLayoutInflater方法其实调用的是PhoneWindow的mLayoutInflater:
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
所以,这几个方法实际上殊途同归,都是通过调用Context的getSystemService方法去获取。获取到的是PhoneLayoutInflater这个实现类,具体的获取过程就不在这里展开分析了。
public class Policy implements IPolicy {
...
public LayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}
}
加载布局
我们用一个简单的例子,介绍下LayoutInflater的用法:
这个例子的目标是在屏幕上展示一个按钮,点击按钮时,会通过LayoutInflater把一个橙色背景的TextView以match_parent的形式加载到一块宽高为300dp的RelativeLayout中。
首先创建两个布局文件:
demo_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:background="#ff750c"
android:text="Hello , world !" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="点击加载" />
<RelativeLayout
android:id="@+id/root"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
RelativeLayout rootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootView = (RelativeLayout) findViewById(R.id.root);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
inflateView();
}
});
}
private void inflateView() {
View insideView = LayoutInflater.from(MainActivity.this).inflate(R.layout.demo_layout, null);
rootView.addView(insideView);
}
}