版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、使用 Android 和 XML 構(gòu)建動態(tài)用戶界面時間:2011年03月07日 10:36:41 來源:IBM-developerWorks 中國 作者:Frank Ableson, 企業(yè)家, MSI Servic簡介: 有幾個網(wǎng)站從事一些非盈利服務(wù),提供一些可輕松設(shè)置和使用的表單來進行民意測驗和數(shù)據(jù)收集。本教程介紹一個簡單的架構(gòu)來為 Android 設(shè)計類似的應(yīng)用程序 允許非編程員從移動用戶收集數(shù)據(jù)的動態(tài)用戶界面。在本教程中,您將創(chuàng)建一個擁有服務(wù)器端和移動端的示例表單引擎。開始之前為更好地利用本文,您應(yīng)該使用 Android SDK 來構(gòu)造 Android 應(yīng)用程序。完成本文之后,您將了解如
2、何使用 HTTP(S) 執(zhí)行從應(yīng)用程序到 web 服務(wù)器的通信,以及如何使用 DOM 解析器解析 XML。在此過程中,您將創(chuàng)建自定義和動態(tài)的用戶界面布局、多線程通信、消息處理程序、以及進程對話框。至少,您將了解 AndroidManifest.xml 和服務(wù)器端腳本編寫。關(guān)于本教程常用縮略詞 API:應(yīng)用程序編程接口 DOM:文檔對象模型 HTML:超文本標記語言 HTTP(S):超文本傳輸協(xié)議安全 IDE:集成開發(fā)環(huán)境 SAX:XML 的簡單 API SDK:軟件開發(fā)工具包 UI:用戶界面 URL:統(tǒng)一資源定位符 XML:可擴展標記語言本教程介紹一個用于在 Android 設(shè)備上進行移動數(shù)據(jù)
3、收集的動態(tài)表單的架構(gòu)。我將首先介紹一個高級架構(gòu),討論這樣一個應(yīng)用程序在數(shù)據(jù)收集的大環(huán)境中的應(yīng)用??焖贋g覽這個已完成的項目,包含每個源文件,對本教程將要介紹的內(nèi)容有一個大概了解。就像 “廚藝展示” 一樣,您使用一些 Java 類從頭開始構(gòu)建這個應(yīng)用程序,每個 Java 類都被小心引入并關(guān)聯(lián)到應(yīng)用程序的其他方面,其中最顯著是一個數(shù)據(jù)模型,這個表單引擎就是基于它構(gòu)造的。最后,您將表單數(shù)據(jù)保存在服務(wù)器上并簡單地查看應(yīng)用程序的服務(wù)器端。數(shù)據(jù)收集我們首先簡要討論數(shù)據(jù)收集,以及如何在使用 Android 移動設(shè)備時輕松實現(xiàn)數(shù)據(jù)收集。一個 Android 數(shù)據(jù)收集框架收集數(shù)據(jù)是計算機時代之前的任務(wù)。計算機已經(jīng)
4、變成一個日常 “訂書釘”,使我們思考、查找和使用信息的方式發(fā)生了革命性的變化。市值數(shù)百億美元的公司要歸功于他們在存儲、檢索和管理海量信息中的高效。今天使用的數(shù)據(jù)庫由各種各樣架構(gòu)的系統(tǒng)供給,包括大型機、客戶服務(wù)器、web 應(yīng)用程序、以及現(xiàn)在的移動應(yīng)用程序。物理存貨和周期計數(shù)應(yīng)用程序是移動計算的早期實用應(yīng)用程序。這些應(yīng)用程序通常是批量數(shù)據(jù)收集,其中硬件需要一個擴展插口(docking station)來上傳收集的信息。從出現(xiàn)到現(xiàn)在,移動應(yīng)用程序市場已經(jīng)走過了很長一段路程,無線連通性和設(shè)備幾乎遍布各種文化和市場,滲透到日常生活的每個方面。盡管數(shù)據(jù)收集方式可能已經(jīng)變得更具流動性,但數(shù)據(jù)收集的核心并沒有
5、發(fā)生太大變化。用戶必須看到一些問題,并且要有一種簡單的響應(yīng)方式。本教程演示如何為 Android 驅(qū)動的移動電話構(gòu)造一個簡單的數(shù)據(jù)收集框架,其中要利用一個 XML 支持的動態(tài)元數(shù)據(jù)結(jié)構(gòu)。應(yīng)用程序架構(gòu)在深入代碼之前,我們先在一個非常高的層面上檢查應(yīng)用程序設(shè)置。Forms Engine 一瞥我們首先瀏覽一下這個 Forms Engine 應(yīng)用程序的各個方面。圖 1 描繪這個應(yīng)用程序與提供各種內(nèi)容的數(shù)據(jù)錄入表單的一個或多個服務(wù)器之間的關(guān)系。圖 1. 應(yīng)用程序架構(gòu)在 圖 1 中,F(xiàn)orm 1 提供 Robotics Competition 的注冊,F(xiàn)orm 2 要求用戶提供關(guān)于他們的汽車維修習(xí)慣的信息
6、。這些表單和 Android 應(yīng)用程序通信使用 HTTP(S)來: 下載表單數(shù)據(jù)。 向用戶顯示表單數(shù)據(jù)并(可選)收集特定于設(shè)備的數(shù)據(jù),比如相機圖像、聲音錄制、GPS 定位、或者羅盤讀數(shù)。 收集用戶提供的數(shù)據(jù)。 將數(shù)據(jù)提交給適當(dāng)服務(wù)器。本教程的服務(wù)器端實現(xiàn)為一對文件:一個描述表單的 XML 文檔和一個負責(zé)記錄表單提交的 PHP 文檔。這個 Android 應(yīng)用程序是一個用 Java 代碼編寫的原生應(yīng)用程序,使用 Android SDK,在 Eclipse 中編碼。表 2 顯示完整應(yīng)用程序的源文件。您可以下載包含所有這些源文件的壓縮文件(參見 下載)。本教程將詳細介紹每個源文件。表 2. 必要的應(yīng)
7、用程序源文件文件名注釋XmlGui.javaAndroid Activity 的入口點XmlGuiForm.java一個表單的高級數(shù)據(jù)模型和方法XmlGuiFormField.java表示一個表單域,持有一個表單的每個字段的元數(shù)據(jù)XmlGuiEditBox.java實現(xiàn)一個文本框類型用戶界面元素XmlGuiPickOne.java實現(xiàn)一個下拉列表類型用戶界面元素RunForm.java使用上述類處理一個表單main.xml應(yīng)用程序用戶界面主頁AndroidManifest.xml此 Android 應(yīng)用程序的部署描述符xmlgui1.xml收集 Robotics 比賽注冊信息的樣例表單xmlg
8、ui1-post.php處理表單提交的 PHP 腳本xmlgui2.xml汽車維修習(xí)慣調(diào)查的樣例表單圖 2 展示本教程末尾完成的應(yīng)用程序在 Eclipse 中的項目結(jié)構(gòu)。(查看 圖 2 的文本版本。)圖 2. Eclipse 中的項目如果您沒有一個正在運行的 Android 開發(fā)環(huán)境,那么現(xiàn)在是安裝 Android 工具的絕好時機。要了解如何設(shè)置一個 Android 開發(fā)環(huán)境,請參閱 參考資料 中必要工具的鏈接,以及一些關(guān)于如何為 Android 開發(fā)應(yīng)用程序的入門文章和教程。熟悉 Android 有助于理解本教程。您已經(jīng)對架構(gòu)和應(yīng)用程序有一個大致了解,現(xiàn)在就開始吧!項目和數(shù)據(jù)模型我們現(xiàn)在已準
9、備好在 Eclipse 中啟動這個 Android 項目,創(chuàng)建允許您為這個 Forms Engine 應(yīng)用程序存儲和管理元數(shù)據(jù)的數(shù)據(jù)模型和類。創(chuàng)建項目創(chuàng)建 Android 應(yīng)用程序從我們熟悉的地方開始:打開 Eclipse 并選擇 File New,如 圖 3 所示。圖 3. 新建一個 Android 應(yīng)用程序這個步驟將啟動 Eclipse New project 向?qū)?。選擇 Android Project(針對 Android 的專業(yè) Java 環(huán)境)。確保向項目提供一個有效的標識符(我使用的是 XMLGUI)。為匹配本教程中介紹的解決方案,在 Properties 下面,指定應(yīng)用程序名為
10、XML GUI,包名為 com.msi.ibm。選擇 Create Activity 復(fù)選框并將 Activity name 指定為 XmlGui,如 圖 4 所示。圖 4. 設(shè)置一個新項目項目創(chuàng)建后,它應(yīng)該非常類似 圖 5 中的圖像。(查看 圖 5 的文本版本。)圖 5. New project 向?qū)倓偼瓿蓵r的 Android 項目現(xiàn)在,項目已創(chuàng)建,確保應(yīng)用程序干凈地構(gòu)建并在 Android Emulator 中運行是一個最佳實踐。注意,有時應(yīng)用程序直到您編輯并保存 Java 源文件時才會構(gòu)建。這導(dǎo)致 Android SDK 工具自動在 gen 文件夾中生成一些文件。如果 Eclipse
11、環(huán)境中的 Problems 選項卡沒有顯示任何條目,那么您可以測試這個應(yīng)用程序。要測試應(yīng)用程序,創(chuàng)建一個 Run 配置,如 圖 6 所示。在 Android Application 列表中,選擇 XmlGui。確保以下值出現(xiàn):XmlGui 位于 Name 字段中,XMLGUI 位于 Project 字段中,com.msi.ibm.XmlGui 位于 Launch 字段中。單擊 Run。圖 6. Run 配置設(shè)置此項目已在 Android 模擬器中創(chuàng)建、配置并正確啟動,現(xiàn)在可以為 Android 創(chuàng)建 XML 驅(qū)動的數(shù)據(jù)收集工具了。回頁首數(shù)據(jù)模型這個應(yīng)用程序的具體細節(jié)要求它向一個用戶顯示輸入元素
12、,驗證數(shù)據(jù),然后將數(shù)據(jù)提交到一個指定服務(wù)器。如果這個應(yīng)用程序只針對新記錄設(shè)置,那么它什么用處也沒有,因為它不支持查詢現(xiàn)有記錄以便編輯或刪除。要向應(yīng)用程序提供足夠的關(guān)于如何顯示數(shù)據(jù)錄入表單的指示,需要一個信息集(通常稱為元數(shù)據(jù))。元數(shù)據(jù)是關(guān)于數(shù)據(jù)的數(shù)據(jù)。簡言之,這個應(yīng)用程序必須理解幾個數(shù)據(jù)元素,包括: Form Name 人們可讀的表單名稱 Form Identifier 這個元數(shù)據(jù)收集的惟一標識符 Submission URL 收集到的數(shù)據(jù)的發(fā)送地址 一個或多個字段 這些字段可能是文本、數(shù)字,或者 “從列表中選擇” 類型的字段幾乎所有種類的問題都映射到這三種類型的用戶界面元素中的一種。例如,可
13、以實現(xiàn)一個復(fù)選框作為一個 Yes 或 No 選擇字段。可以實現(xiàn)多重選擇(multi-select)作為多選字段。當(dāng)然,您可以隨意擴展本教程中展示的代碼。對于您的應(yīng)用程序,使用場景如下:您在參加一個活動,其中您可以注冊一個或多個項目。您可以填寫一張注冊表,也可以等到回家后登錄該組織的網(wǎng)站進行注冊。在本例中,您將假定一位用戶將通過在一個 Android 設(shè)備上下載一個動態(tài)表單,以便在現(xiàn)場從他的手機填寫一張簡單表單,提供申請者的姓名、性別和年齡。清單 1 顯示了 xmlgui1.xml 的內(nèi)容,該文件表示一個 Robotics 俱樂部活動的注冊表單。清單 1. xmlgui1.xml 注意關(guān)于這個
14、XML 文檔的以下幾點: 這個 XML 非常容易解析,這要歸功于元素屬性的廣泛使用。之所以使用這種方法,原因是與多個子元素和標記相比,它使提取數(shù)據(jù)更容易。以這種方式使用屬性還能保持較小的下載大小,并有助于保持較低的解析時間。 submitTo 屬性告知應(yīng)用程序,數(shù)據(jù)收集完成后將要發(fā)送到的位置。 每個 field 元素同時提供一個字段名和一個標簽的屬性。盡管這些值是相關(guān)的,但您希望每個 name 屬性的值都保持惟一,以便接收應(yīng)用程序能夠正確解析并處理它們。您還應(yīng)該向用戶提供一個提示性 label 值,提示用戶什么種類的數(shù)據(jù)將進入一個特定字段。 您可以輕松擴展這個方法以包含每個字段的默認值,一個用
15、于驗證的 regex 表達式,或者一個獲取關(guān)于特殊字段的更多信息的鏈接。 options 字段用作 choice 字段的一個受限列表?;玖私鈹?shù)據(jù)模型后,現(xiàn)在看看負責(zé)將這個 XML 數(shù)據(jù)轉(zhuǎn)化為一個有用應(yīng)用程序的代碼。回頁首表示數(shù)據(jù)解析數(shù)據(jù)是一個非常機械的練習(xí),將在本教程后面展示。在檢查解析流程之前,應(yīng)用程序需要某個位置來在內(nèi)存中存儲和管理這個元數(shù)據(jù)。出于這個目的,您擁有兩個 Java 類,一個用于表單,一個用于表示表單字段。我們首先查看 清單 2 中的 XmlGuiForm.java。清單 2. XmlGuiForm.javapackage com.msi.ibm;import java.ut
16、il.Vector;import java.util.ListIterator;import .URLEncoder;public class XmlGuiForm private String formNumber; private String formName; private String submitTo; public Vector fields; public XmlGuiForm() this.fields = new Vector(); formNumber = ; formName = ; submitTo = loopback; / do nothing
17、but display the results / getters & setters public String getFormNumber() return formNumber; public void setFormNumber(String formNumber) this.formNumber = formNumber; public String getFormName() return formName; public void setFormName(String formName) this.formName = formName; public String getSub
18、mitTo() return submitTo; public void setSubmitTo(String submitTo) this.submitTo = submitTo; public Vector getFields() return fields; public void setFields(Vector fields) this.fields = fields; public String toString() StringBuilder sb = new StringBuilder(); sb.append(XmlGuiForm:n); sb.append(Form Num
19、ber: + this.formNumber + n); sb.append(Form Name: + this.formName + n); sb.append(Submit To: + this.submitTo + n); if (this.fields = null) return sb.toString(); ListIterator li = this.fields.listIterator(); while (li.hasNext() sb.append(li.next().toString(); return sb.toString(); public String getFo
20、rmattedResults() StringBuilder sb = new StringBuilder(); sb.append(Results:n); if (this.fields = null) return sb.toString(); ListIterator li = this.fields.listIterator(); while (li.hasNext() sb.append(li.next().getFormattedResult() + n); return sb.toString(); public String getFormEncodedData() try i
21、nt i = 0; StringBuilder sb = new StringBuilder(); sb.append(Results:n); if (this.fields = null) return sb.toString(); ListIterator li = this.fields.listIterator(); while (li.hasNext() if (i != 0) sb.append(&); XmlGuiFormField thisField = li.next(); sb.append(thisF + =); String encstring = n
22、ew String(); URLEncoder.encode(String) thisField.getData(),encstring); sb.append(encstring); return sb.toString(); catch (Exception e) return ErrorEncoding; 關(guān)于 XmlGuiForm 類,有幾個重要項目需要注意:1. 這里有 4 個成員變量: o formNumber:這是服務(wù)器端表單分發(fā)機制的惟一標識符。o formName:這是表單標題,向用戶提供上下文和確認。o submitTo:這是應(yīng)用程序提交輸入的數(shù)據(jù)(經(jīng)過驗證)的 URL。這
23、個值也可以是一個 loopback。在 loopback 場景中,數(shù)據(jù)顯示給用戶,而不是提交到服務(wù)器。這對測試比較有用。o fields:這是被模板化以持有表單的字段數(shù)據(jù)的 Vector 類。清單 3 展示了 XmlGuiFormField.java 的細節(jié)。2. 一系列針對這些變量的 getters 和 setters。3. toString() 和 getFormattedResults() 方法負責(zé)生成 XmlGuiForm 類的可讀摘要。4. getFormEncodedData() 方法在準備將數(shù)據(jù)提交到 submitTo 屬性中指定的 URL 時使用。5. 這個代碼不使用嚴格連接的
24、 java.lang.String 類,而是采用一個 StringBuilder 作為構(gòu)建理想數(shù)據(jù)字符串的一個更內(nèi)存高效的方法。6. URLEncoder 類用于準備將數(shù)據(jù)提交到服務(wù)器。這使得數(shù)據(jù)實際上看起來就像一個傳統(tǒng) HTML 表單創(chuàng)建的一樣。7. 這個應(yīng)用程序的一些潛在擴展包括: o 元數(shù)據(jù)本地存儲或緩存使重復(fù)任務(wù)更快運行。o 本地存儲在提交前一段時間內(nèi)記錄數(shù)據(jù)。o GPS 記錄 使用位置數(shù)據(jù)標記每條記錄。現(xiàn)在看看 清單 3 中 XmlGuiFormField 類的構(gòu)造情況。清單 3. XmlGuiFormField.javapackage com.msi.ibm;/ class to
25、handle each individual formpublic class XmlGuiFormField String name; String label; String type; boolean required; String options; Object obj; / holds the ui implementation / or the EditText for example / getters & setters public String getName() return name; public void setName(String name) this.nam
26、e = name; public String getLabel() return label; public void setLabel(String label) this.label = label; public String getType() return type; public void setType(String type) this.type = type; public boolean isRequired() return required; public void setRequired(boolean required) this.required = requi
27、red; public String getOptions() return options; public void setOptions(String options) this.options = options; public String toString() StringBuilder sb = new StringBuilder(); sb.append(Field Name: + + n); sb.append(Field Label: + this.label + n); sb.append(Field Type: + this.type + n); sb
28、.append(Required? : + this.required + n); sb.append(Options : + this.options + n); sb.append(Value : + (String) this.getData() + n); return sb.toString(); public String getFormattedResult() return + = + (String) this.getData() + ; public Object getData() if (type.equals(text) | type.equals
29、(numeric) if (obj != null) XmlGuiEditBox b = (XmlGuiEditBox) obj; return b.getValue(); if (type.equals(choice) if (obj != null) XmlGuiPickOne po = (XmlGuiPickOne) obj; return po.getValue(); / You could add logic for other UI elements here return null; 現(xiàn)在更詳細地查看 XmlGuiFormField 類。 有 6 個類級別成員: 1. name
30、持有字段名稱 這是數(shù)據(jù)值的字段名稱,類似于 HTML 值的表單域名稱或數(shù)據(jù)庫列名。2. label 持有字段說明或顯示給用戶的值。3. type 表明要創(chuàng)建的用戶界面字段的風(fēng)格。 text 表明這個字段是用一個 EditText 字段實現(xiàn)的,用于輸入字母數(shù)字字符。這是最常用的值。 numeric 也是一個 EditText,但它局限于數(shù)字值。 choice 使這個字段成為一個下拉列表。4. required 是一個 Boolean 值,標志字段是否為必要字段。如果字段必要且沒有填充,則當(dāng)用戶試圖提交表單時,將向用戶顯示一條錯誤消息。5. options 是一個字符串值,用于為一個選擇字段傳送一
31、個可用選項列表。這個字段對其他字段可用,可能用作一個 regex 表達式以進行驗證,也可以被覆蓋以指定一個默認值。6. obj 表示用戶界面小部件。例如,這個變量持有一個 EditText,用于文本或數(shù)字字段。對于一個選擇字段,obj 成員包含一個 spinner 小部件。這個方法將在本教程后面進一步解釋。 不出所料,這些變量擁有幾個 getters 和 setters。 toString() 和 getFormattedResult() 方法都利用 getData() 方法,我們將稍后解釋。 在 XmlGuiFormField 類中,您需要管理多種類型數(shù)據(jù),因此代碼需要明確表示數(shù)據(jù)如何存儲和
32、訪問。getData() 方法檢查這個類型字段并在 obj 字段上執(zhí)行一個類型設(shè)置,以便與存儲的對象正確交互。如果您想向這個框架添加新字段類型,可以擴展 getData() 方法來支持這種新字段類型(參見 清單 3 末尾附近的注釋)。您現(xiàn)在有一種方法來存儲和管理元數(shù)據(jù)。現(xiàn)在可以檢查應(yīng)用程序的運行情況,然后將各部分組合起來。收集用戶數(shù)據(jù)您已經(jīng)創(chuàng)建了 Activity 主屏幕布局,現(xiàn)在可以創(chuàng)建用戶界面表單來收集數(shù)據(jù)了。在本例中,您將創(chuàng)建一個 Robotics Club Registration 表單和一個 Auto Maintenance 調(diào)查表單。使用元數(shù)據(jù)這個應(yīng)用程序取決于 Android 程
33、序員動態(tài)操作用戶界面的能力。在本教程前面,您檢查了 main.xml 文件,該文件定義 XmlGui 類(主 Activity)的屏幕布局。如果您總是必須在設(shè)計或編譯時定義用戶界面元素,那么應(yīng)用程序幾乎不可能是它的當(dāng)前形式。幸運的是,您并不局限于那種方式。DisplayForm() 方法負責(zé)將這個元數(shù)據(jù)轉(zhuǎn)換為用戶界面元素,以便搜集數(shù)據(jù)。其代碼分為兩個主要功能區(qū)域:用戶界面元素的布局和提交按鈕的處理。首先,檢查布局邏輯。這段代碼負責(zé)將 XmlGuiForm 對象轉(zhuǎn)換為一個真正的屏幕表單。清單 8 展示了這段代碼。清單 8. 布局邏輯 private boolean DisplayForm() t
34、ry ScrollView sv = new ScrollView(this); final LinearLayout ll = new LinearLayout(this); sv.addView(ll); ll.setOrientation(android.widget.LinearLayout.VERTICAL); / walk through the form elements and dynamically create them, / leveraging the mini library of tools. int i; for (i=0;itheForm.fields.size
35、();i+) if (theForm.fields.elementAt(i).getType().equals(text) theForm.fields.elementAt(i).obj = new XmlGuiEditBox(this,(theForm.fields.elementAt(i).isRequired() ? * : ) + theForm.fields.elementAt(i).getLabel(),); ll.addView(View) theForm.fields.elementAt(i).obj); if (theForm.fields.elementAt(i).getT
36、ype().equals(numeric) theForm.fields.elementAt(i).obj = new XmlGuiEditBox(this,(theForm.fields.elementAt(i).isRequired() ? * : ) + theForm.fields.elementAt(i).getLabel(),); (XmlGuiEditBox)theForm.fields.elementAt(i).obj).makeNumeric(); ll.addView(View) theForm.fields.elementAt(i).obj); if (theForm.f
37、ields.elementAt(i).getType().equals(choice) theForm.fields.elementAt(i).obj = new XmlGuiPickOne(this,(theForm.fields.elementAt(i).isRequired() ? * : ) + theForm.fields.elementAt(i).getLabel(), theForm.fields.elementAt(i).getOptions(); ll.addView(View) theForm.fields.elementAt(i).obj); Button btn = n
38、ew Button(this); btn.setLayoutParams(new LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams. WRAP_CONTENT); ll.addView(btn); btn.setText(Submit); btn.setOnClickListener(new Button.OnClickListener() public void onClick(View v) / check if this form is Valid if (!CheckForm() Alert
39、Dialog.Builder bd = new AlertDialog.Builder(ll.getContext(); AlertDialog ad = bd.create(); ad.setTitle(Error); ad.setMessage(Please enter all required (*) fields); ad.show(); return; if (theForm.getSubmitTo().equals(loopback) / just display the results to the screen String formResults = theForm.getF
40、ormattedResults(); Log.i(tag,formResults); AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext(); AlertDialog ad = bd.create(); ad.setTitle(Results); ad.setMessage(formResults); ad.show(); return; else if (!SubmitForm() AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext(); Ale
41、rtDialog ad = bd.create(); ad.setTitle(Error); ad.setMessage(Error submitting form); ad.show(); return; ); setContentView(sv); setTitle(theForm.getFormName(); return true; catch (Exception e) Log.e(tag,Error Displaying Form); return false; 您必須預(yù)期超出單個屏幕可以容納的內(nèi)容的更多字段的可用性,因此,使用一個 ScrollView 作為父視圖或容器。在該 S
42、crollView 中,您使用一個垂直 LinearLayout 來將各種用戶界面小部件組織為一個垂直列。這種方法非常簡單: 您通過 XmlGuiForm 實例的 fields 成員中包含的 XmlGuiFormField 對象來列舉。 根據(jù)請求的字段的類型,一個不同的用戶界面元素被實例化并添加到 LinearLayout。您將快速檢查不同的 UI 小部件。當(dāng) UI 元素被創(chuàng)建并添加到這個線性布局中后,您將整個 ScrollView 實例添加到這個屏幕的內(nèi)容并將表單名指定為屏幕標題。圖 9 展示了為用戶輸入準備就緒的一個 Robotics 俱樂部注冊屏幕。這個表單是 清單 1 中的 XML 數(shù)
43、據(jù)的處理結(jié)果。圖 9. 運行中的 Robotics 注冊表單我們來看看為這個應(yīng)用程序創(chuàng)建的不同的自定義用戶界面小部件?;叵胍幌拢覀?yōu)檫@個應(yīng)用程序定義了三種類型的數(shù)據(jù)輸入字段:文本、數(shù)值和選項。這三種類型通過兩個不同的自定義小部件實現(xiàn):XmlGuiEditBox 和 XmlGuiPickOne。文本和數(shù)值非常相似,因此可以利用相同的 EditView 方法,但使用不同的輸入過濾器來在字母數(shù)字和僅允許數(shù)字之間切換。清單 9 展示了 XmlGuiEditBox 類的代碼。清單 9.XmlGuiEditBox 類package com.msi.ibm;import android.content.C
44、ontext;import android.util.AttributeSet;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.EditText;import android.text.method.DigitsKeyListener;public class XmlGuiEditBox extends LinearLayout TextView label; EditText txtBox; public
45、XmlGuiEditBox(Context context,String labelText,String initialText) super(context); label = new TextView(context); label.setText(labelText); txtBox = new EditText(context); txtBox.setText(initialText); txtBox.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams .FILL_PARENT,ViewGroup.LayoutParams.
46、WRAP_CONTENT); this.addView(label); this.addView(txtBox); public XmlGuiEditBox(Context context, AttributeSet attrs) super(context, attrs); / TODO Auto-generated constructor stub public void makeNumeric() DigitsKeyListener dkl = new DigitsKeyListener(true,true); txtBox.setKeyListener(dkl); public Str
47、ing getValue() return txtBox.getText().toString(); public void setValue(String v) txtBox.setText(v); XmlGuiEditBox 類擴展 LinearLayout 類并包含一個文本標簽來描述要求的輸入,以及一個 EditText 來實際收集輸入的數(shù)據(jù)。所有對象初始化都在構(gòu)造函數(shù)中完成。這也許被視為糟糕的表單,但如果您對這種方法不滿意,那么這只是留給您的一個練習(xí)。我們還將討論三種方法。getValue() 和 setValue() 方法正是您想要的。它們是用于與 EditText 字段交互的 getter 和 setter。第三種方法 makeNumeric() 僅在設(shè)置數(shù)值表單類型時才調(diào)用。DigitsKeyListener 的實例用于過濾任何非數(shù)值
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 電纜加工合同范例
- 維修總價包干合同范例
- 農(nóng)改房合同范例
- 工業(yè)平車出售合同范例
- 江西鋼材采購合同范例
- 禁止銷售合同范例
- 管道施工單價合同范例
- 商標策劃合同范例
- 租公建合同范例
- 設(shè)備外包維保合同范例
- 羽毛球社團工作總結(jié)
- 高三英語一輪復(fù)習(xí)七選五命題分析課件
- 安徽省合肥市廬陽區(qū)2023-2024學(xué)年三年級上學(xué)期期末數(shù)學(xué)試卷
- 以問題為導(dǎo)向的教學(xué)設(shè)計與實踐
- 2024年大學(xué)試題(經(jīng)濟學(xué))-流通經(jīng)濟學(xué)筆試歷年真題薈萃含答案
- 光伏運維合同
- 氧氣吸入法健康宣教
- 江蘇省南京市建鄴區(qū)重點中學(xué)2023-2024學(xué)年七年級上學(xué)期期末數(shù)學(xué)試題(含答案)
- 建設(shè)施工三級安全教育課件
- 電能質(zhì)量技術(shù)監(jiān)督培訓(xùn)課件
- 大班音樂:戲說臉譜課件
評論
0/150
提交評論