Saturday, June 26, 2010

將自己設計xml的Layout轉成View:LayoutInflater

一般來講,我們用LayoutInflater做一件事:inflate

inflate這個方法總共有四種形式,目的都是把xml表述的layout轉化為View。其中只有一個我個人比較常用,View inflate(int resource, ViewGroup root),另外三個,其實目的和這個差不多。這裡簡單說一下它的用法,相信已經開始實踐的人都差不多用過了。
int resource,也就是resource/layout文件在R文件中對應的ID,這個必須指定。而ViewGroup root則可以是null,null時就只創建一個resource對應的View,不是null時,會將創建的view自動加為root的child。

問題就是為什麼要調用inflate(),而不是用setContentView()讓它自己去inflate?

setContentView()一旦調用, layout就會立刻被貼上UI。而inflate只會把Layout形成一個以view類實現成的對象。到時若有需要時再用 setContentView(view)把它貼上。

以上內容轉載至eoeAndroid論壇 

==========================================

一般來講,我們用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中獲取




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

  1. public static LayoutInflater from(Context context) {  
  2.     LayoutInflater LayoutInflater =  
  3.             (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  4.     if (LayoutInflater == null) {  
  5.         throw new AssertionError("LayoutInflater not found.");  
  6.     }  
  7.     return LayoutInflater;  
 3. LayoutInflater.inflate()將Layout文件轉換為View,顧名思義,專門供Layout使用的Inflater。
雖然 Layout也是View的子類,但在android中如果想將xml中的Layout轉換為View放入.java代碼中操作,只能通過 Inflater,而不能通過findViewById(),這一段描述有誤,看如下代碼。看下面文檔寫的已經很清楚。
  1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:orientation="vertical"   
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"> 
  5.       
  6.     <LinearLayout android:id="@+id/placeslist_linearlayout"  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:orientation="vertical"> 
  10.           
  11.   LinearLayout> 
  12. >
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() 會出現NullPointException。

(1)Activity中的findViewById()
 (2)View中的findViewById()
 以上轉載至醋溜的部落格

No comments: