android开发笔记之LayoutInflater的理解和使用

1.一个demo

(1)有一个布局文件Hy_video_bar.xml (res\layout)

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

    <ImageView
        android:id="@+id/video_pre"
        android:layout_width="100dip"
        android:layout_height="100dip"
        android:layout_alignParentLeft="true"
        android:src="@drawable/ic_vidcontrol_play_pre" />

    <ImageView
        android:id="@+id/video_playing"
        android:layout_width="100dip"
        android:layout_height="100dip"
        android:layout_toRightOf="@id/video_pre"
        android:src="@drawable/ic_vidcontrol_play" />

    <ImageView
        android:id="@+id/video_next"
        android:layout_width="100dip" 
        android:layout_height="100dip"
        android:layout_toRightOf="@id/video_playing"
        android:src="@drawable/ic_vidcontrol_play_next" />

</RelativeLayout>

    现在我们要引入进来,使用。怎么办呢,这时候,我们就可以考虑使用Android的LayoutInflater,来解决这个问题。


(2)定义成员变量

    protected final View mViewBar;
    protected final ImageView playPreView;
    protected final ImageView playNextView;

(3)引入布局文件

        LayoutInflater inflater = LayoutInflater.from(context);
        this.mViewBar = inflater.inflate(R.layout.hy_video_bar, null);
        mPlayPauseReplayView = (ImageView) mViewBar.findViewById(R.id.video_playing); 
       // mPlayPauseReplayView = new ImageView(context);
        //mPlayPauseReplayView.setBackgroundResource(R.drawable.bg_vidcontrol);
        mPlayPauseReplayView.setScaleType(ScaleType.CENTER);
        mPlayPauseReplayView.setFocusable(true);
        mPlayPauseReplayView.setClickable(true);
        mPlayPauseReplayView.setOnClickListener(this);
        
       // addView(mPlayPauseReplayView, wrapContent);
        
        playPreView = (ImageView) mViewBar.findViewById(R.id.video_pre); 
        playPreView.setImageResource(R.drawable.ic_vidcontrol_play_pre);
       // playPreView.setBackgroundResource(R.drawable.bg_vidcontrol);
        playPreView.setScaleType(ScaleType.CENTER);
        playPreView.setFocusable(true);
        playPreView.setClickable(true);
        playPreView.setOnClickListener(this);
        
        playNextView = (ImageView) mViewBar.findViewById(R.id.video_next); 
        playNextView.setImageResource(R.drawable.ic_vidcontrol_play_next);
       // playNextView.setBackgroundResource(R.drawable.bg_vidcontrol);
        playNextView.setScaleType(ScaleType.CENTER);
        playNextView.setFocusable(true);
        playNextView.setClickable(true);
        playNextView.setOnClickListener(this);
        
        addView(mViewBar, wrapContent);


2.LayoutInflater分析:

  (1) 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;

而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。
具体作用:
     对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
     对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。

(2)获得 LayoutInflater 实例的三种方式

    LayoutInflater inflater = getLayoutInflater(); //调用Activity的getLayoutInflater()
    LayoutInflater localinflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    LayoutInflater inflater = LayoutInflater.from(context);

(3)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)  

示意代码:

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

(4)setContentView和inflate区别

setContentView()一旦调用, layout就会立刻显示UI;而inflate只会把Layout形成一个以view类实现成的对象,有需要时再用setContentView(view)显示出来

一般在activity中通过setContentView()将界面显示出来,eg:

setContentView(R.layout.example);     
button = (Button)findViewById(R.id.button);    


但是如果在非activity中如何对控件布局设置操作了,这需LayoutInflater动态加载.

< TextView
android:id="@+id/tview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ATAAW.COM"
/>
< Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:text="按钮"
/>

在程序中动态加载以上布局。
LayoutInflater flater = LayoutInflater.from(this);
View view = flater.inflate(R.layout.example, null);
获取布局中的控件。
button = (Button) view.findViewById(R.id.button);//这里的view为上面获取的view对象
textView = (TextView)view.findViewById(R.id.tview);

LayoutInflater.inflate()将Layout文件转换为View,专门供Layout使用的Inflater。虽然Layout也是View的子类,但在android中如果想将xml中的Layout转换为View放入.java代码中操作,只能通过Inflater,而不能通过findViewById()。


(5)findViewById有两种形式
R.layout.xx是引用res/layout/xx.xml的布局文件(inflate 方法),R.id.xx是引用布局文件里面的组件,组件的id是xx(findViewById方法)。所有的组件id都能用R.id.xx来查看,但是组件不在setContentView()里面的layout中就无法使用,Activity.findViewById()会出现空指针异常
a. activity中的findViewById(int id)
b. View 中的findViewById(int id)
不同点是LayoutInflater是用来找layout下xml布局文件,并且实例化!而findViewById()是找具体xml下的具体 widget控件(如:Button,TextView等)。


参考资料:

1.http://blog.csdn.net/chenqiumiao/article/details/7703048

Android LayoutInflater的使用

2.http://weizhulin.blog.51cto.com/1556324/311450

Android 中LayoutInflater的使用

你可能感兴趣的:(android,LayoutInflater)