android中LayoutInflater以及inflate

来源:互联网 发布:linux 卸载openoffice 编辑:程序博客网 时间:2024/05/22 04:48

转:http://hi.baidu.com/aspxdiyer/item/5879980402843519eafe388f

一、LayoutInflater


LayoutInflater其实是在res/layout/下找到xml布局文件,并且将其实例化,这个和findViewById()有点相似,后者是找xml布局文件下的具体widget控件(如Button、TextView等)

作用:

1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;

2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。


LayoutInflater 是一个抽象类,在文档中如下声明:

public abstract class LayoutInflater extends Object


获得 LayoutInflater 实例的三种方式


1. LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()

例:View toastRoot = getLayoutInflater().inflate(R.layout.toast, null);


2. LayoutInflater localinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);


3. LayoutInflater inflater = LayoutInflater.from(context);

例:View convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_contact, null);



二、inflate

通俗的说,inflate就相当于将一个xml中定义的布局找出来.因为在一个Activity里如果直接用findViewById()的话,对应的是setConentView()的那个layout里的组件.


因此如果你的Activity里如果用到别的layout,比如对话框上的layout,你还要设置对话框上的layout里的组件(像图片ImageView,文字TextView)上的内容,你就必须用inflate()先将对话框上的layout找出来,然后再用这个layout对象去找到它上面的组件,如:

  

  View view=View.inflate(this,R.layout.dialog_layout,null);

TextView dialogTV=(TextView)view.findViewById(R.id.dialog_tv);

  

  dialogTV.setText("abcd");

  

  如果组件R.id.dialog_tv是对话框上的组件,而你直接用this.findViewById(R.id.dialog_tv)肯定会报错.




一个界面xml布局文件仅仅inflate一次即可,然后将这个实例保存起来,如果inflate两次,在发现问题根源之前,可能会出现一些极为怪异的问题。比如:

[java]view plaincopyprint?
  1. LayoutInflater inflater = getLayoutInflater();
  2. viewList.add(inflater.inflate(R.layout.default_view,null));
  3. viewList.add(inflater.inflate(R.layout.musiclist_view,null));
  4. viewList.add(inflater.inflate(R.layout.networkmusic_view,null));


在这里实例化了3个布局文件,作为ViewPager切换时的布局。如果想获取这些布局的实例,应直接用保存在viewList里面的实例,而不是再次inflate一个出来,否则,如果你在第二次inflate出来的布局文件上寻找某一个控件,然后设置控件的值,然后更新界面,你会发现界面根本就没反应,因为那个控件根本就不是属于第一个布局文件的实例的。


这样才是正确的做法。注释的是错误的做法。



转:http://blog.csdn.net/yueyueniao96/article/details/7485025

LayoutInflater用法

LayoutInflater是一个用来实例化XML布局为View对象

应用程序运行时会预先加载资源中的布局文件,如果layout布局中的资源比较多,会影响性能,所以可以选择LayoutInflater方式用的时候加载,这样减轻了应用程序运行时很多负担

public View inflate(int resource,ViewGroup root)

从指定的XML资源中填充一个新的视图

参数resource:将要加载的XML布局id,例如R.layout.list_item

参数root:父视图,可选项,一般为Null

public static LayoutInflater from(Context context)

从给定的context获取LayoutInflater


可以通过如下三种方式获取LayoutInflater

第一种:

        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);        View myView = inflater.inflate(R.layout.main, null);

第二种:与第一种方法相同,即from方法封装了getSystemService(...)等

        LayoutInflater inflater = LayoutInflater.from(context);        View myView = inflater.inflate(R.layout.main, null);

第三种:getLayoutInflater()方法是Activity的方法,归根到底还是第一种方式

        LayoutInflater inflater = getLayoutInflater();        View myView = inflater.inflate(R.layout.main, null);

所以我们在加载布局的时候可以用setContentView直接设置,然后通过findViewById()来获取控件的id


例如:我们可以用4种方式加载main.xml布局文件,不过LayoutInflater一般多用于ListView等地方,

如BaseAdapter的getView()方法会用到:http://www.cnblogs.com/loulijun/archive/2011/12/28/2305016.html

复制代码
package com.loulijun.demo6;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.widget.Button;import android.widget.TextView;public class Demo6Activity extends Activity {    private Button btn;    private TextView tv;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //----------第一种方式----------//        setContentView(R.layout.main);//        btn = (Button)findViewById(R.id.btn);//        tv = (TextView)findViewById(R.id.tv);        //----------第二种方式----------//        LayoutInflater inflater = getLayoutInflater();        //----------第三种方式----------//        LayoutInflater inflater = LayoutInflater.from(this);        //----------第四种方式----------        LayoutInflater inflater = (LayoutInflater)this.getSystemService(                Context.LAYOUT_INFLATER_SERVICE);        View view = inflater.inflate(R.layout.main, null);        setContentView(view);        btn = (Button)view.findViewById(R.id.btn);        tv = (TextView)view.findViewById(R.id.tv);       btn.setOnClickListener(new Button.OnClickListener()       {        @Override        public void onClick(View v) {            //...        }                  });    }
复制代码


使用setContentView(R.layout.main)设置布局后布局会立刻显示,而使用inflate()方法加载的布局文件得到的是一个View视图对象,在需要的时候再setContentView(view)即可。在Activity中一般只需要setContentView即可,如果是非Acitivity,则需要使用LayoutInflater来动态加载控制控件。

 

 


转:http://lpqsun-126-com.iteye.com/blog/1158070

在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如 Button、TextView等)。
具体作用:
1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;

2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。

LayoutInflater 是一个抽象类,在文档中如下声明:

Java代码 收藏代码
  1. publicabstractclass LayoutInflaterextends Object

获得 LayoutInflater 实例的三种方式:

Java代码 收藏代码
  1. 1. LayoutInflater inflater = getLayoutInflater();//调用Activity的getLayoutInflater()
  2. 2. LayoutInflater localinflater = (LayoutInflater)context.getSystemService
  3. (Context.LAYOUT_INFLATER_SERVICE);
  4. 3. LayoutInflater inflater = LayoutInflater.from(context);

其实,这三种方式本质是相同的,从源码中可以看出:

getLayoutInflater():

Activity 的 getLayoutInflater() 方法是调用 PhoneWindow 的getLayoutInflater()方法,看一下该源代码:

Java代码 收藏代码
  1. public PhoneWindow(Context context) {
  2. super(context);
  3. mLayoutInflater = LayoutInflater.from(context);
  4. }

可以看出它其实是调用 LayoutInflater.from(context)。

LayoutInflater.from(context):

Java代码 收藏代码
  1. publicstatic LayoutInflater from(Context context) {
  2. LayoutInflater LayoutInflater =
  3. (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  4. if (LayoutInflater ==null) {
  5. thrownew AssertionError("LayoutInflater not found.");
  6. }
  7. return LayoutInflater;
  8. }

可以看出它其实调用 context.getSystemService()。

结论:所以这三种方式最终本质是都是调用的Context.getSystemService()。

inflate 方法
通过 sdk 的 api 文档,可以知道该方法有以下几种过载形式,返回值均是 View 对象,如下:

Java代码 收藏代码
  1. public View inflate (int resource, ViewGroup root)
  2. public View inflate (XmlPullParser parser, ViewGroup root)
  3. public View inflate (XmlPullParser parser, ViewGroup root,boolean attachToRoot)
  4. public View inflate (int resource, ViewGroup root,boolean attachToRoot)

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

示意代码:

Java代码 收藏代码
  1. LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
  2. View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));
  3. //EditText editText = (EditText)findViewById(R.id.content);// error
  4. EditText editText = (EditText)view.findViewById(R.id.content);

同时在此讲讲让我去API中去理解这四个函数的原因吧!嘿嘿!你肯定又会多学一招!
在Activity中:
大家是否知道,在setContentView(new MySurfaceView(this))后,此Activity中声明的View控件,
如:TextView 为什么引用不到layout布局文件中的控件ID呢!初一看能够应用到,但是为什么编译就报空指针呢!原因:在setContentView(new MySurfaceView(this))后,此时的View变为了根视图了,虽然能应用到TextView对应的ID,但是我在 MySurfaceView中根本就没有这个对象,所以就报空指针咯!解决办法:
View view = LayoutInflater.from(this).inflate(R.layout.passover, null);注:每解析一次都会产生不同的对象
然后你再引用没问题,使用自如了。

0 0
原创粉丝点击