資源resource(上)、XML解析(XmlPullParser)

resource是java源代碼之外的靜態信息。例如layout。resource作爲文件存放在res/目錄下面,除了res/raw/外,Android會自動解析,例如layout文件,我們不需要自己去解析XML封裝。我們之前用過res/layout/,以及res/anim/之前已經用過。

Image:文件存放在res/drawable/,存放應用的icon。

Raw:res/raw/,程序所需的任意格式的文件,但是系統不會對其進行解析,也既Adroid Framework並不需要的。

String,color,array,dimension:在res/values中,將這些常量和我們的java源代碼分離,這樣便於程序的國際化或者本地化中。

XML,位於res/xml/,這些靜態的XML文件用於保存程序的數據和結構。


String

定義resource

在resource中定義,有利於國際化或者本地化,即便不需要翻譯爲其他語言,可以很方便去檢測或者修改,而無須在程序的各處去尋找,因此這是一種通用的處理方式。Android還支持常用的擴展方式,通過style,可以設置不同的格式。String在res/values/strings.xml中定義,根節點是resources,例如如下:

[html] view plaincopy
  1. <resources>  
  2.     <string name="quick">The quick brown fox...</string>  
  3.     <string name="laughs">He who laughs last...</string  
  4.     <string name="c20_my_name">My name is %1$s %2$s</string>  
  5.     <string name="c20_rich_text">My name is &lt;b&gt;%1$s&lt;/b&gt; &lt;i&gt;%2$s&lt;/i&gt;</string>  
  6. </resources>  
  如果字符串中包含"和',就需要用\"或者\',如果字符串中只有一個單引號,可以使用"xxxxx 's xxxxxx"的方式,用雙引號括起來。

在layout文件中,用@string/element_name,例如@string/quick來引用內容,在java源代碼中,用R.string.element_name作爲ID,並用getString()來獲取,例如getString(R.string.laughs)。

支持string format

例如我們在strngs.xml中定義:<string name="c20_my_name">My name is %1$s %2$s</string>,裏面的佔位符號可以被變量替換,例如

[java] view plaincopy
  1. String strFormat = getString(R.string.c20_my_name);  
  2. String strResult = String.format(strFormat,"Tim","Martin");  

那麼strResult則爲:My name is Tim Martin。

rich Text

如果我們需要rich string,我們還可以通過HTML對格式進行定義,之前學習過的是通過webkit來顯示。然而我們也可以在TextView中顯示帶有Html格式。

例如:<string name="c20_rich_text">My name is &lt;b&gt;%1$s&lt;/b&gt;  &lt;i>%2$s&lt;/i&gt;</string>在程序中,我們將內容一個通過textview來顯示,一個通過顯示html格式的textview,最後一個通過webkit來顯示:

[java] view plaincopy
  1. TextView lable = (TextView)findViewById(R.id.c20_lable);  
  2. TextView lable2 = (TextView)findViewById(R.id.c20_lable2);  
  3. WebView web = (WebView)findViewById(R.id.c20_web);  
  4.           
  5. String strFormat = getString(R.string.c20_rich_text);  
  6. String strResult = String.format(strFormat,"Tim","Martin");  
  7. String strResult2 = String.format(strFormat,TextUtils.htmlEncode("Tim"),  
  8.                                   TextUtils.htmlEncode("Martin"));   
  9.   
  10. /* 上面,strResult和strResult2的結果都是一樣的My name is <b>Time<b> <i>Martin</i>  
  11.  * 關鍵是下面setText(Html.fromHtml(strResult)),將一個簡單的HTML轉換爲一個帶格式的文本對象 
  12.  */  
  13.       
  14. lable.setText(strResult);  
  15. lable2.setText(Html.fromHtml(strResult2));  
  16. web.loadData(strResult, "text/html""UTF-8");  

2012.11.2補充:insikuTextUtils.htmlEncode 是爲了防止輸入的字符串含有HTML的一些預留字符,比如< > &, 這些字符在HTML中有特殊含義, 得轉換字符實體

圖片Picture

  圖片文件可以是PNG,JPEG,和GIF,推薦使用PNG,不建議使用GIF,文件放置在res/drawable/下,Android有三個文件夾drawable-hdpi/drawable-mdpi/和drawable-ldpi對應不同的尺寸,實際上並沒有什麼太大的區別。假設文件名爲foo.png,則在資源XML文件中名稱爲@drawable/foo,在Java源代碼中該資源的ID則爲R.drawable.foo。

   例子:將一個png文件app_icon放到drawable中,我放入了drawable-hdpi/中,在Adroid XML文件如下,運行結果如圖,中間的書本icon就是我們的ImageButton,只需要通過android:src來指出圖片的位置。

[html] view plaincopy
  1. ......  
  2. <ImageButton android:id="@+id/c20_format2"  
  3.              android:layout_width="wrap_content"  
  4.              android:layout_height="wrap_content"  
  5.              android:src="@drawable/app_icon"/>  
  6. ......  

xml文件

  xml文件可以用戶儲存我們的數據,或者作爲配置文件等。xml文件可以位於res/xml目錄下面,例如我們在該目錄下放置一個xml文件words.xml,如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <ListItems desrciption="Put the entry as the item in Android List">  
  3.     <Entry value="One" />  
  4.     <Entry value="Two" />  
  5.     <Entry value="Three" />  
  6.     <Entry value="Four" />  
  7.     <Entry value="Five" />  
  8.     <Entry value="Six" />  
  9.     <entry>Hello</entry>  
  10. </ListItems>  

  XmlPullParser可以用於解釋xml文件。這裏有兩種xml的常見格式:<entry>Hello</entry>和<Entry value="Six" />,在Android XML中使用後者,而這種方式在XmlPullParser中處理也非常方便。它的使用方式歸納如下:

  1. XmlPullParser通過next(),依次向下檢查
  2. XmlPullParser是事件驅動,如果檢測到END_DOCUMENT,應當停止繼續檢測
  3. XmlPullParser是事件驅動,當檢測到START_TAG,可以讀出<AAAA bbbb=xxxx c=yyyyy>的內容,其中AAAA可通過getName()來獲取,屬性的個數,可通過getAttributeCount()獲取,屬性的名詞和內容可分別通過getAttributeName(index)和getAttributeValue(index)來獲取。
  4. XmlPullParser是事件驅動,如果是END_TAG,則爲</AAAA>,可以通過getName()來獲得AAAA的內容
  5. 對於<entry>Hello</entry>這種方式,如果要獲取中間的數值,則事件爲XmlPullParser.TEXT,可通過getText()來獲取內容。
  6. 由於xml文件可能書寫不正確,或者我們在解釋的過程中處理不正確,應當使用異常捕獲的方式來處理

下面的例子,我們將上述的words.xml分析處理,將Entry數值作爲listActivity的每個item的內容。

[java] view plaincopy
  1. /* 1. XmlPullParser通過next(),依次向下檢查 
  2.  * 2. XmlPullParser是事件驅動,如果檢測到 END_DOCUMENT,應當停止繼續檢測 
  3.  * 3. XmlPullParser是事件驅動,當檢測到START_TAG,可以讀出<AAAA bbbb=xxxx c=yyyyy>的內容,其中AAAA可通過getName()來獲取,屬性的個數,可通過getAttributeCount()獲取,屬性的名詞和內容可分別通過getAttributeName(index)和getAttributeValue(index)來獲取。 
  4.  * 4. XmlPullParser 是事件驅動,如果是END_TAG,則爲</AAAA>,可以通過getName()來獲得AAAA的內容 
  5.  * 5. 對於<entry>Hello</entry>這種方式,如果要獲取中間的數值,則事件爲XmlPullParser.TEXT, 可通過getText()來獲取內容。 
  6.  * 6. 由於xml文件可能書寫不正確,或者我們在解釋的過程中處理不正確,應當使用異常捕獲的方式來處理 
  7. */  
  8. public class Chapter20Test3 extends ListActivity{  
  9.     private ArrayList<String> items = new ArrayList<String>();  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.           
  13.         /*步驟1:進行特定xml文件words的解析,對應第6點,應採用異常捕獲防止程序出錯*/   
  14.         try{  
  15.             /* 步驟2:獲取xml文件,並給給出XmlPullParser對象*/    
  16.             XmlPullParser xpp = getResources().getXml(R.xml.words);  
  17.             /* 步驟3:通過循環,逐步解析XML,直至xml文件結束,對應第1點和第2點*/   
  18.             while(xpp.getEventType()!=XmlPullParser.END_DOCUMENT){  
  19.                 /* 步驟4:獲取目標ListItems的解析,並將之用method:ListItems來處理,對應第3點 */  
  20.                 if(xpp.getEventType() == XmlPullParser.START_TAG){  
  21.                     if(xpp.getName().equals("ListItems")){  
  22.                         getItems(xpp);  
  23.                     }  
  24.                 }  
  25.                 xpp.next();  
  26.             }  
  27.         }catch(Throwable t){  
  28.             Toast.makeText(this"Failed:" + t.toString(), 2000).show();  
  29.         }  
  30.         setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,items));  
  31.     }  
  32.       
  33.     /* 解析<ListItems ... >.... </Listitem>的內容,獲取每個entry的value的值,注意對異常的處理*/  
  34.     private void getItems(XmlPullParser xpp) throws Throwable{  
  35.         while(true){  
  36.             xpp.next();  
  37.             /*<ListItems> ...</ListItems>的內容已經檢索完畢,或者文件結束,都退出處理*/  
  38.             if((xpp.getEventType() == XmlPullParser.END_TAG && xpp.getName().equals("ListItems"))   
  39.               || xpp.getEventType() == XmlPullParser.END_DOCUMENT)  
  40.                 break;  
  41.   
  42.             if(xpp.getEventType()==XmlPullParser.START_TAG) {  
  43.                 /*觀測點:對第3點的處理,讀出屬性的名字和數值*/  
  44.                 if(xpp.getName().equals("Entry")){  
  45.                     for(int i = 0; i < xpp.getAttributeCount() ; i ++){  
  46.                         if(xpp.getAttributeName(i).equals("value")){  
  47.                             items.add(xpp.getAttributeValue(i));  
  48.                         }  
  49.                     }  
  50.                 }  
  51.                 /*觀測點:對第5點的處理,處理<name>value</name>*/  
  52.                 if(xpp.getName().equals("entry")){  
  53.                     xpp.next();  
  54.                     if(xpp.getEventType()==XmlPullParser.TEXT)  
  55.                         items.add(xpp.getText());  
  56.                 }  
  57.             }  
  58.         }  
  59.   
  60.     }  
  61.   
  62.     @Override  
  63.     protected void onListItemClick(ListView l, View v, int position, long id) {  
  64.         super.onListItemClick(l, v, position, id);  
  65.         Toast.makeText(this, items.get(position), Toast.LENGTH_LONG).show();  
  66.     }  
  67.       
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章