LayoutInflater类

严宇
2023-12-01

一、LayoutInflater 类简介

  LayoutInflater类作用是将layout的xml布局文件实例化为View类对象,LayoutInflater的作用类似于 findViewById()。不同的是LayoutInflater类是用来找layout文件夹下的xml布局文件,并将该布局实例化为View对象以供使用;而 findViewById()则是寻找当前布局下的具体widget控件(如:Button,TextView等)。可以想象,这里有个层次关系,也就是View对象是个大的画纸,而widget则是画纸中的各种元素。LayoutInflater主要用于实现画纸, findViewById()则是操控画纸上的各种元素。实际上,在调用setContentView(int layoutResID)后,也经历了类似LayoutInflater的过程,依照我们的习惯,在当前布局下,即可调用 findViewById()来操控我们的控件。同样,在实例化的View对象中,也能使用 findViewById()来对该对象的控件进行操控。
  使用的例子有很多,例如,我们并不希望某些元素立即在Activity可见,但又希望在某个时候将其设为可见,又不切换Activity的情况下,于是我们便想到了使用setContentView(int layoutResID)这一方法来切换布局。但仔细想想,如果需要反复调用,代码将会变得极为复杂。于是,我们可以准备一张已经完成好的布局(View),需要的时候,即可使用setContentView(View view)方法,将该布局设为可见。

二、获取 LayoutInflater 实例
LayoutInflater 是不能 new 出来的。获取 LayoutInflater 实例的方法有三种:

  1.LayoutInflater inflater = getLayoutInflater();

  2.LayoutInflater inflater = LayoutInflater.from(this);       

  3.LayoutInflater inflater = (LayoutInflater)Context.getSystemService(LAYOUT_INFLATER_SERVICE);

其实,这三种方式本质是相同的。第一种方法中,Activity 的 getLayoutInflater() 方法是调用 PhoneWindow 的getLayoutInflater()方法。先来看看PhoneWindow中getLayoutInflater()的源码:

public PhoneWindow(Context context) {  
        super(context);  
        mLayoutInflater = LayoutInflater.from(context);  
} 

可见,它调用了 LayoutInflater.from(this) 方法,也就是上述的第二种方法。那么再来看看 LayoutInflater.from(this) 的源码:

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;   
}

可见,无论你是用哪种方法,到了最后都是调用getSystemService(LAYOUT_INFLATER_SERVICE);方法。


三、获取View对象并操控内部控件

到此为止问题就简单多了。通过文档查阅可知,可使用以下几种方法实例化布局:

  public View inflate (int resource, ViewGroup root)  
  public View inflate (XmlPullParser parser, ViewGroup root)  
  public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)  
  public View inflate (int resource, ViewGroup root, boolean attachToRoot) 

例如:

View layoutA;
layoutA = ((LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.a, null);

要获取View中的控件,可使用以下方法:

Button bt1 = (Button) layoutA.findViewById(R.id.bt1);

注意,千万不要在当前Activity下尝试获取View中的控件。因为对于当前Activity来说,该View中的控件是不可见的。因此不能使用findViewById(),而要使用layoutA.findViewById()。


四、示例

该例子功能为在两个布局间切换,并且通过输出Log来判断切换是否成功。

MainActivity.java

package com.plusjun.change;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	View layoutA, layoutB;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		inflaterA();
		inflaterB();
		changeToA();
	}

	void inflaterA(){
		layoutA = ((LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.a, null);
		
		Button bt1 = (Button) layoutA.findViewById(R.id.bt1);
		Button bt2 = (Button) layoutA.findViewById(R.id.bt2);
		
		bt1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				changeToB();
			}
		});
		
		bt2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Log.i("a","a---------------------------------------");
			}
		});
	}
	
	void inflaterB(){
		layoutB = ((LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.b, null);
		
		Button bt1 = (Button) layoutB.findViewById(R.id.bt1);
		Button bt2 = (Button) layoutB.findViewById(R.id.bt2);
		
		bt1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				changeToA();
			}
		});
		
		bt2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Log.i("b","b---------------------------------------");
			}
		});
	}
	
	void changeToA(){
		setContentView(layoutA);
	}
	
	void changeToB(){
		setContentView(layoutB);
	}
}


a.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="this is A, click change to b.xml" />

    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="log" />

</LinearLayout>

b.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="this is B, click change to a.xml" />

    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="log" />

</LinearLayout>

a.xml 和 b.xml 两者间仅有第一个Button中的text不同。


http://www.cnblogs.com/merryjd/archive/2013/01/08/2851092.html
在此表示感谢。
转载请注明来源,版权归原作者所有,未经同意严禁用于任何商业用途。
微博:http://weibo.com/theworldsong
邮箱:theworldsong@foxmail.com
 类似资料: