|
XmlR
存取識別符號
在上一章談了 XML描述檔中介面元件的各種「android:」開頭的屬性。要使用一個介面元件,第一件事就是定義出介面描述檔。大部分的介面元件(如 LinearLayout、TextView)不需要在程式中作後續處理,因此可以直接描述(例如我們前面定義過的 TextView 文字顯示元件「身高(cm)」)。但對於那些將在程式中被參考(reference)到的介面元件(如按鈕 Button、文字輸入欄位 EditText),我們需要先行在 XML描述檔中,定義該介面元件的「android:id」識別符號屬性。這麼一來在程式碼中我們要操作這個介面元件(取出欄位中輸入的資料、取得按下按鈕事件...)時,就能透過「android:id」識別符號來調用這個介面元件。 <EditText android:id="@+id/height"
/>前面章節提過,寫作時最好將 XML 描述檔屬性分行列出,以易於閱讀(增加可讀性)。而我們的範例卻將 android:id 屬性直接擺在 EditText 標籤後。其實這麼做同樣是基於易於閱讀的考量。當然你也可以將「android:id」屬性分行列出,或是將「android:id」屬性放在屬性列表的中間或最後頭,這些作法都是允許的,本書中一律採用將 android:id 屬性直接擺在介面元件標籤後的寫法。 android:id 屬性的內容長得比較特別: @+id/height 「height」是這個介面元件的 android:id。以後的程式中會使用「R.id.height」來取得這個介面元件。「@+id」 的意思是我們可以通過這個識別符號來控制所對應的介面元件,「R」類別會自動配置一個位址給這個介面元件。 「R」類別的內容則可以透過查看 R.java 得知。 XML 描述檔與 R.java 檔在 Android 系統中,我們使用 XML 來定義 UI。但是有些稍微有經驗的開發者可能會有疑問: 「用 XML 來描述介面固然方便,但是對於手機程式來說,直接用 XML 檔案是不是太占空間了?」。 沒錯,如果 Android 是直接使用 XML 來儲存介面描述到手機上的話,一定會佔用比起現在大的多的檔案空間。解決的方法是Android 並不直接使用 XML 檔案,而是透過 Android 開發工具,自動將 XML 描述檔轉換成資源檔案。一旦應用程式要操作某個介面元件,或是使用任何種類的資源(字串、圖片、圖示、音效...),都使用索引來查詢。 當你建立一個 BMI 新專案,打開位於 「gen/com/demo/android/bmi」 目錄下的 「R.java」檔,你可以看到如下的程式碼: /* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.demo.android.bmi;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040000;
}
}在照著前一章新增了 XML 描述後,再次打開打開 「gen/com/demo/android/bmi」 目錄下的 「R.java」 檔 ,你可以看到如下的程式碼: /* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.demo.android.bmi;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int height=0x7f050000;
public static final int result=0x7f050003;
public static final int submit=0x7f050002;
public static final int suggest=0x7f050004;
public static final int weight=0x7f050001;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040000;
}
}我們看到在 R.java 檔案中,分別有 attr (屬性)、drawable (圖片、圖示)、id (識別符號)、layout (介面描述)、string (文字) 這幾種資源型態,就 XML 描述檔中的 id 來說,開發工具會根據 XML 描述檔中指定的 id,生成對應的資源,並自動指定一個位址。 Google 官方文件是這麼解釋「R.java」檔案的作用的: A project's R.java file is an index into all the resources defined in the file. You use this class in your source code as a sort of short-hand way to refer to resources you've included in your project. This is particularly powerful with the code-completion features of IDEs like Eclipse because it lets you quickly and interactively locate the specific reference you're looking for. The important thing to notice for now is the inner class named "layout", and its member field "main". The Eclipse plugin noticed that you added a new XML layout file and then regenerated this R.java file. As you add other resources to your projects you'll see R.java change to keep up. 有了「R.java」做中介,在 XML 描述檔中,我們可以透過 @[類型]/[識別符號] 這樣的語法來為某個介面元件提供識別符號,以供程式控制。 例如,我們可以用 「@+id/height」來為對應供輸入身高數字的 EditText 元件提供識別符號。 將字串抽離 XML當我們在 res 資料夾中新增各種一個 XML 檔案,或是一張圖片時,開發工具會從 res 資料夾中蒐集,並將各種資源彙整成一個索引,自動產生出 R.java 檔。 透過這個特性,我們可以進一步加工我們的 XML 描述檔,讓介面更易於維護。 開啟 res/values/strings.xml 原始的內容為 <?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">BMI</string>
</resources>裡面只定義了一個字串「app_name」,用來表示應用程式名稱(在之後講解 AndroidManifest.xml 檔案時將會用到)。 我們看到表示字串的格式為 <string name="識別代號">文字敘述</string> 我們將上一章中的敘述抽取出來,整理進 strings.xml 檔案。 完整的 strings.xml 檔案如下: <?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">BMI</string>
<string name="bmi_height">身高 (cm)</string>
<string name="bmi_weight">體重 (kg)</string>
<string name="bmi_btn">計算 BMI 值</string>
<string name="bmi_result">你的 BMI 值是 </string>
</resources>在 strings.xml 檔案中,我們在原本的 app_name 字串外,自行定義了另外幾個字串。如果我們再次開啟 「R.java」檔,我們會發現檔案中的 string 類別中也自動索引了上面定義好的字串: public static final class string {
public static final int app_name=0x7f040000;
public static final int bmi_btn=0x7f040003;
public static final int bmi_result=0x7f040004;
public static final int bmi_height=0x7f040001;
public static final int bmi_weight=0x7f040002;
}接著,我們把這些字串應用到之前定義好的 XML 描述檔中。透過使用 @string/[識別符號] 這樣存取 string 類型的格式,來取代 main.xml 檔案中原本寫死的文字敘述。 完整的程式碼如下: <?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/bmi_height"
/>
<EditText android:id="@+id/height"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="integer"
android:text=""
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/bmi_weight"
/>
<EditText android:id="@+id/weight"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="integer"
android:text=""
/>
<Button android:id="@+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bmi_btn"
/>
<TextView android:id="@+id/result"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
<TextView android:id="@+id/suggest"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>
</LinearLayout>再次運行 Android 虛擬機器,我們看到與前一節完全相同的介面。但就介面而言,透過將描述字串統一集中在 「string.xml」 中,我們以後要修改介面時更有彈性了。 至此我們已經完成了 BMI 應用程式負責「顯示 (View)」的部份。 新增 XML 檔案我們在前面都只修改到開發工具幫我們產生的檔案, 而事實上,我們所有在 「res」 目錄中所做的修改,開發工具都會自動搜尋,將之整理到「R.java」中。因此我們也可以在「src/values」中建立自己的文字描述檔案。 我們這就在「res/values」目錄中建立一個 「advice.xml」檔,裡面將包含 BMI 程式算出 BMI 值後將給予的建議文字,完整的檔案如下: <?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="advice_light">你該多吃點</string>
<string name="advice_average">體型很棒喔</string>
<string name="advice_heavy">你該節食了</string>
</resources>打開「R.java」檔,我們發現「advice_light」、「advice_average」、「advice_heavy」也已整理進「R.java」檔的索引中,以供程式調用。 Android 中所有的資源檔案(圖片、XML等)命名都必須使用英文小寫,檔名中間只允許加上底線「」符號。其他的檔名都會造成無法正常產生R.java 檔,讓你的程式無法編譯。 那麼接下來,我們就開始進入到了解 Android 程式流程的部分吧。 對於本章,您還期望知道什麼樣的內容呢?請在下方提出建議! |
Sign in to add a comment
我在新增XML檔案的時候卡住還久的,不知道怎麼新增,也許這邊可以補充講解說明一下新增辦法。謝謝
我是在values資料夾上用滑鼠右鍵New-->file,file name就打advice.xml。
b9507...@mail.ntust.edu.tw, 我的添加方法: values資料夾上用滑鼠右鍵New,在弹出的菜单中选择others,然后在弹出在New对话框中选择XML类型,并输入文件名称后按Finish即可。
請問 @id/name 跟 @+id/name 有何差異,謝謝您。
目前看到xml中都是同一種語言,是否有support多國語言呢? 另外,在Eclipse中按alt+/可以顯示提示,在這邊也有用喔~給大家參考
simonsu.mail, 支援多國語言, 不想找原文看的話, 在實體書裡有教
不知為何,我的R.java不會自動配合values/.xml更新耶
kiwiberry77, 隨便改一下 xml 檔內容, 再 refresh 一下應該就會改變了
<EditText? android:id="@+id/height"
与 <TextView? ... 文字显示文本输入框 标识与引用都是 height 有点要弄混、晕乎乎的感觉一個是 id, 一個是 string 呀, 兩者在不同分類下. 簡單地說, string 是預先定義好的字串拿過來用的, id 是定義給程式碼呼叫的. id 後面接的是在這個檔案中預先定義給程式操控的參數, string 後面接的是從 res/values 目錄的 xml 檔案中預先定義的字串代號.
这个我知道,就好象有个天天在一起的同事和单位门岗养的狗叫相同名字一样,反正觉得怪怪的,当然能分开,有工作不会叫上狗一起做,从饭店带回来的剩饭菜不会让同事吃
這麼說有道理, 改了 :)
不好意思請問:R.java不是在gen裡面嗎?文中好像是說src呢??
huzshih, 是的, 1.5 版之後 R.java 從 src/ 換到 gen/ 了, 謝謝指正