在 实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用 来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如 Button、TextView等)。
具体作用:
1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。
LayoutInflater 是一个抽象类,在文档中如下声明:
- public abstract class LayoutInflater extends Object
获得 LayoutInflater 实例的三种方式:
- LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
- LayoutInflater localinflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
- LayoutInflater inflater = LayoutInflater.from(context);
其实,这三种方式本质是相同的,从源码中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是调用 PhoneWindow 的getLayoutInflater()方法,看一下该源代码:
- public PhoneWindow(Context context) {
- super(context);
- mLayoutInflater = LayoutInflater.from(context);
- }
可以看出它其实是调用 LayoutInflater.from(context)。
LayoutInflater.from(context):
- 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;
- }
可以看出它其实调用 context.getSystemService()。
结论:所以这三种方式最终本质是都是调用的Context.getSystemService()。
另外getSystemService()是Android很重要的一个API,它是Activity的一个方法,根据传入的NAME来取得对应的Object,然后转换成相应的服务对象。以下介绍系统相应的服务。
传入的Name 返回的对象 说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view
ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源的服务
ALARM_SERVICE AlarmManager 闹钟的服务
NOTIFICATION_SERVICE NotificationManager 状态栏的服务
KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
LOCATION_SERVICE LocationManager 位置的服务,如GPS
SEARCH_SERVICE SearchManager 搜索的服务
VEBRATOR_SERVICE Vebrator 手机震动的服务
CONNECTIVITY_SERVICE Connectivity 网络连接的服务
WIFI_SERVICE WifiManager Wi-Fi服务
TELEPHONY_SERVICE TeleponyManager 电话服务
inflate 方法
通过 sdk 的 api 文档,可以知道该方法有以下几种过载形式,返回值均是 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)
public View inflate(int Resourece,ViewGroup root)
作用:填充一个新的视图层次结构从指定的XML资源文件中
reSource:View的layout的ID
root: 生成的层次结构的根视图
return 填充的层次结构的根视图。如果参数root提供了,那么root就是根视图;否则填充的XML文件的根就是根视图。
其余几个重载的inflate函数类似。
1:public View inflate (int resource, ViewGroup root)
reSource:View的layout的ID
root:如果为null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
2: public View inflate ( XmlPullParser parser, ViewGroup root)
parser:你需要解析xml的解析接口
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
3: public View inflate ( XmlPullParser parser, ViewGroup root, boolean attachToRoot)
parser:你需要解析View的xml的解析接口
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
attachToRoot:
ture:也就将此解析的xml作为View根
fase:则为默认的xml,做为根视图View
4:public View inflate (int resource, ViewGroup root, boolean attachToRoot)
resource:View的layout的ID
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
attachToRoot:
ture:也就将此解析的xml作为View根
fase:则为默认的xml,做为根视图View
示意代码:
- LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));
- //EditText editText = (EditText)findViewById(R.id.content);// error
- EditText editText = (EditText)view.findViewById(R.id.content);
setContentView和inflate的区别找了一些资料。以下演示代码:
public class MyInflate extends Activity{
private TextView tv;
public void OnCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
//tv = (TextView) findViewById(R.id.tv);
LayoutInflater inflate = LayoutInflater.from(this);
View view = inflate.inflate(R.layout.main,null);
setContentView(view);
}
}
上述注释掉的代码和没有注释掉的代码两种情况是相同的。
区别:
setContentView()一旦调用, layout就会立刻显示UI;而inflate只会把Layout形成一个以view类实现成的对象,有需要时再用setContentView(view)显示出来。一般在activity中通过setContentView()将界面显示出来,但是如果在非activity中如何对控件布局设置操作了,这就需要LayoutInflater动态加载。