LayoutInflater

LayoutInflater的使用,在實際開發種LayoutInflater這個類還是非常有用的,它的作用類似於 findViewById(),
不同點是LayoutInflater是用來找layout下xml佈局文件,並且實例化!而findViewById()是找具體xml下的具體 widget控件(如:Button,TextView等)。
爲了讓大家容易理解我做了一個簡單的Demo,主佈局main.xml裏有一個TextView和一個Button,當點擊Button,出現 Dialog,而這個Dialog的佈局方式是我們在layout目錄下定義的custom_dialog.xml文件(裏面左右分佈,左邊 ImageView,右邊TextView)。

下面我將詳細的說明Demo的實現過程:
1、新建一個 Android工程,我們命名爲LayoutInflaterDemo.
2、修改main.xml佈局,裏面主要在 原來基礎上增加了一個Button.代碼如下:
view plaincopy to clipboardprint?
<?xml version="1.0"    
encoding="utf-8"?>   
<LinearLayout    
xmlns:android="http://schemas.android.com/apk/res/android"   
    android:orientation="vertical"   
    android:layout_width="fill_parent"   
    android:layout_height="fill_parent"   
    >   
<TextView     
    android:layout_width="fill_parent"    
    android:layout_height="wrap_content"    
    android:text="@string/hello"   
    />   
<Button   
    android:id="@+id/button"   
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:text="ShowCustomDialog"   
    />   
</LinearLayout>   
3.定義對話框的佈局方式,我們在layout目錄下,新建一個名爲 custom_dialog.xml文件具體代碼如下:
view plaincopy to clipboardprint?
<?xml version="1.0"    
encoding="utf-8"?>   
<LinearLayout    
xmlns:android="http://schemas.android.com/apk/res/android"   
              android:orientation="horizontal"   
              android:layout_width="fill_parent"   
              android:layout_height="fill_parent"   
              android:padding="10dp"   
              >   
    <ImageView android:id="@+id/image"   
               android:layout_width="wrap_content"   
               android:layout_height="fill_parent"   
               android:layout_marginRight="10dp"   
               />   
    <TextView android:id="@+id/text"   
              android:layout_width="wrap_content"   
              android:layout_height="fill_parent"   
              android:textColor="#FFF"   
              />   
</LinearLayout>   
4.修改主程序LayouInflaterDemo.java代碼如下:
view plaincopy to clipboardprint?
package com.android.tutor;   
import android.app.Activity;   
import android.app.AlertDialog;   
import android.content.Context;   
import android.os.Bundle;   
import android.view.LayoutInflater;   
import android.view.View;   
import android.view.View.OnClickListener;   
import android.widget.Button;   
import android.widget.ImageView;   
import android.widget.TextView;   
public class LayoutInflaterDemo extends Activity implements    
OnClickListener {   
       
    private Button button;   
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);   
           
        button = (Button)findViewById(R.id.button);   
        button.setOnClickListener(this);   
    }   
    @Override   
    public void onClick(View v) {   
           
        showCustomDialog();   
    }   
       
    public void showCustomDialog()   
    {   
        AlertDialog.Builder builder;   
        AlertDialog alertDialog;   
        Context mContext = LayoutInflaterDemo.this;   
           
        //下面倆種方法都可以   
        ////LayoutInflater inflater = getLayoutInflater();   
        LayoutInflater inflater = (LayoutInflater)    
mContext.getSystemService(LAYOUT_INFLATER_SERVICE);   
        View layout = inflater.inflate(R.layout.custom_dialog,null);   
        TextView text = (TextView) layout.findViewById(R.id.text);   
        text.setText("Hello, Welcome to Mr Wei's blog!");   
        ImageView image = (ImageView) layout.findViewById(R.id.image);   
        image.setImageResource(R.drawable.icon);   
        builder = new AlertDialog.Builder(mContext);   
        builder.setView(layout);   
        alertDialog = builder.create();   
        alertDialog.show();   
    }   
}   
5、最後執行之,點擊Button,將得到上述效果。

 

 

 

 


 

一般來講,我們用LayoutInflater做一件事:inflate。inflate這個方法總共有四種形式,目的都是把xml表述的layout轉化爲View。This class is used to instantiate layout XML file into its corresponding View objects . It is never be used directly -- use getLayoutInflater() or getSystemService(String)getLayoutInflater() or getSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on

 

1. Context.public abstract Object getSystemService (String name) :Return the handle to a system-level service by name. The class of the returned object varies by the requested name. 具體參見文檔。

 

2. 2種獲得LayoutInflater的方法

(1)通過SystemService獲得

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

(2)從給定的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;
    }
,LayoutInflater 需要Context 來得到實例

(3)二者區別:實質是一樣的,請看源碼


Java代碼 複製代碼
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;   
}  

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

 

3. LayoutInflater.inflate()

將Layout文件轉換爲View,顧名思義,專門供Layout使用的Inflater。雖然Layout也是View的子類,但在android中如果想將xml中的Layout轉換爲View放入.java代碼中操作,只能通過Inflater,而不能通過findViewById(),這一段描述有誤,看如下代碼 。看下面文檔寫的已經很清楚。

 


Xml代碼 複製代碼
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"    
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content">  
       
    <LinearLayout android:id="@+id/placeslist_linearlayout"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:orientation="vertical">  
           
    </LinearLayout>      
</ScrollView>  

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">
	
	<LinearLayout android:id="@+id/placeslist_linearlayout"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:orientation="vertical">
		
	</LinearLayout>	
</ScrollView>

 LinearLayout linearLayout = (LinearLayout) findViewById(R.id.placeslist_linearlayout);

linearLayout.addView(place_type_text);

這是可運行的,這上面的xml中,LinearLayout不再是Layout的代表,而只是一個普通的View。

 

 

 

 

4. findViewById有2中形式

R.layout.xx 是引用res/layout/xx.xml的佈局文件(inflate方法),R.id.xx是引用佈局文件裏面的組件,組件的id是xx...(findViewById方法)。看看R.java配置文件吧,R對文件分類管理,多寫幾個layout.xml後你會發現,所有的組件id都能用R.id.xx來查看,但是組件不在setContentView()裏面的layout中就無法使用,Activity.findViewById()會出現空指針異常 。

(1)Activity中的findViewById()

public View findViewById (int id)

                  Finds a view that was identified by the id attribute from the XML that was processed in
onCreate(Bundle)
                   ReturnsThe view if found or null otherwise.

(2)View中的findViewById()

public final View findViewById (int id)
                    Look for a child view with the given id. If this view has the given id, return this view.

Parameters      

id The id to search for.



Returns      The view that has the given id in the hierarchy or null

轉自:http://blog.163.com/guozioo@126/blog/static/64086947201052925641679/

發佈了15 篇原創文章 · 獲贊 8 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章