jQuery Mobile設(shè)計(jì)Android通訊錄(第一章)
本文假設(shè)讀者已對(duì)jQuery Mobile有一定的初步認(rèn)識(shí),同時(shí)也初步了解Android的一些基本用法。
本教程的結(jié)構(gòu)
本系列教程安排如下。在***部分中,我們將介紹在應(yīng)用程序中的運(yùn)行界面截圖,說(shuō)明整個(gè)應(yīng)用的流程走向及結(jié)構(gòu),并說(shuō)明一些如何在Android的Webview控件中通過(guò)Javascript與后端的JAVA應(yīng)用程序交互的一些技巧和知識(shí)點(diǎn),其中會(huì)介紹jQuery Mobile中的各種重要頁(yè)面元素。在本系列的第二部分中,將介紹如何在通訊錄應(yīng)用中新增加、編輯和刪除帳號(hào)。在本系列的第三部分中,將介紹如何增加通訊錄,其中會(huì)介紹用到一個(gè)工具類。在第四部分,將重點(diǎn)介紹如何使用Jackson JSON處理庫(kù)去將JAVA對(duì)象和JSON對(duì)象之間進(jìn)行轉(zhuǎn)換,并介紹了項(xiàng)目整個(gè)工程如何配置,如何根據(jù)Android的圖標(biāo)設(shè)計(jì)***實(shí)踐去設(shè)計(jì)圖標(biāo),***總結(jié)全系列的教程。
頁(yè)面流程結(jié)構(gòu)
下面來(lái)講解應(yīng)用的頁(yè)面流程結(jié)構(gòu)。在這個(gè)應(yīng)用中,每個(gè)通訊錄都與帳號(hào)相關(guān)聯(lián)的,也就是說(shuō),每個(gè)帳號(hào)的用戶中可以建立多個(gè)通訊錄,就象gmail一樣。當(dāng)Android應(yīng)用啟動(dòng)后,會(huì)檢查應(yīng)用中是否已經(jīng)建立了帳號(hào),如果是***次啟動(dòng),是不存在帳號(hào)的,那么會(huì)提示用戶新建立一個(gè)帳號(hào),如下圖所示:
一旦建立了帳號(hào)后,就可以進(jìn)入通訊錄的初始頁(yè)面了,如下圖:
可以看到,上圖是按字母順序?qū)νㄓ嶄浥判颉.?dāng)用戶點(diǎn)“Add”按鈕時(shí),則會(huì)顯示讓用戶輸入具體的通訊錄的頁(yè)面,如下邊左邊***張圖所示
而在通訊錄列表中,用戶可以點(diǎn)選某一個(gè)已存在的聯(lián)系人的信息進(jìn)行查看,查看的實(shí)際效果圖如上圖的第二張圖所示,這里用戶可以對(duì)信息進(jìn)行編輯修改,再保存,保存后會(huì)回到
通訊錄列表的界面。同時(shí),用戶如果點(diǎn)“delete”按鈕,會(huì)顯示出如下圖的界面,詢問(wèn)用戶是否真正要?jiǎng)h除該用戶的聯(lián)系信息。
而在整個(gè)應(yīng)用程序中,由于考慮到要處理的記錄數(shù)量會(huì)大,以及移動(dòng)設(shè)備的處理能力,一個(gè)友好的做法是在處理數(shù)據(jù)時(shí),添加一個(gè)表示當(dāng)前進(jìn)度的進(jìn)度的圖標(biāo),如下圖:
總結(jié)一下,整個(gè)應(yīng)用的實(shí)際流程如下圖所示:
#p#
jQuery Mobile 頁(yè)面設(shè)計(jì)
現(xiàn)在我們來(lái)看下如何使用jQuery Mobile框架去設(shè)計(jì)頁(yè)面元素。在jQuery Mobile框架設(shè)計(jì)的HTML頁(yè)中,通常是一個(gè)頁(yè)面中有一個(gè)頁(yè)面容器,而頁(yè)面容器中則存在多個(gè)頁(yè)面。頁(yè)面容器以date-role=“page”作標(biāo)識(shí),而普通頁(yè)面以date-role=“content”作標(biāo)識(shí)。在一個(gè)頁(yè)面中,頁(yè)面頭部和尾部是可選的部分。在我們的這個(gè)應(yīng)用中,有兩個(gè)頁(yè)面是都有頭部和尾部的,一個(gè)頁(yè)面沒有頭部和尾部,下面看示例代碼:
- <div data-role="page">
- <div data-role="header">...</div>
- <div id="contentWithHeaderAndFooter1" data-role="content">...</div>
- <div data-role="footer">...</div>
- <div data-role="header">...</div>
- <div id="contentWithHeaderAndFooter2" data-role="content">...</div>
- <div data-role="footer">...</div>
- <div id="contentWithNoHeaderAndFooter" data-role="content">...</div>
- </div>
在上面的代碼中,展示了如何在一個(gè)容器頁(yè)面中包含了三個(gè)頁(yè)面,其中有2個(gè)頁(yè)面是有頁(yè)頭和頁(yè)腳的,分別用data-role="header"和data-role="footer"標(biāo)識(shí)。
在本應(yīng)用中,創(chuàng)建帳號(hào)、通訊錄列表和進(jìn)度圖標(biāo)都是以內(nèi)容頁(yè)的形式出現(xiàn),而在ListPage.html中將會(huì)有一個(gè)頁(yè)面容器包裹著它們,而DetailPage.html中也有一個(gè)頁(yè)面容器,其中包含三個(gè)頁(yè)面,分別是“空的通訊錄”,“已經(jīng)存在的通訊錄”和“提示是否刪除通訊錄”,下圖表示了它們之間的結(jié)構(gòu)關(guān)系:
如何整合前端代碼和Android后端Java代碼
在本篇教程中,我們將重點(diǎn)學(xué)習(xí)如何在jQuery Mobile設(shè)計(jì)的前端頁(yè)面HTML/JAVASCRPT中,去訪問(wèn)Android中后端的Java應(yīng)用程序,以及它們之間如何互相交互。要知道,jQuery Mobile只是幫助開發(fā)者用自己熟悉的HTML/Javascript等知識(shí)去開發(fā)出統(tǒng)一界面,能在不同平臺(tái)上運(yùn)行的應(yīng)用,但它并沒有跟Android整合的機(jī)制,因此我們分三個(gè)部分去講解如何:
1. 通過(guò)Javascript去訪問(wèn)Android的Java代碼
2. Android Java應(yīng)用訪問(wèn)前端Javascript/HTML代碼
3. 在前后端交互中參數(shù)的類型問(wèn)題
通過(guò)Javascript去訪問(wèn)Android的Java代碼
首先來(lái)學(xué)習(xí)如何通過(guò)Javascript去訪問(wèn)Android的Java代碼。Android提供了一個(gè)方法,可以供JavaScript 去訪問(wèn)Java應(yīng)用,這個(gè)方法是位于android.webkit.WebView類中的addJavascriptInterface(Object object, String interfaceName) 方法。這個(gè)方法允許從JavaScript代碼去訪問(wèn)在WebView中運(yùn)行的Java類中的public方法。要注意的是,WebView其實(shí)也是android.view.View中的一種。WebView是Android中顯示HTML頁(yè)面和JavaScript的瀏覽器。其中,addJavascriptInterface方法中的obj為和javascript通信的應(yīng)用程序,interfacename為提供給JavaScript調(diào)用的名稱,下面這個(gè)圖,清楚地顯示了兩者之間的調(diào)用關(guān)系:
下面這段代碼,顯示了ContactsActivity 這個(gè)類的實(shí)例,如何通過(guò)addJavascriptInterface方法,對(duì)外暴露為一個(gè)Javascript對(duì)象,對(duì)外的接口名稱為“contactSupport”。其中ContactsActivity中有很多public方法,它向外暴露了其中的deleteContact()方法,
- import android.webkit.WebView;
- import android.app.Activity;
- ...
- public class ContactsActivity extends Activity {
- WebView webView;
- ...
- public void onCreate(Bundle savedInstanceState) {
- ...
- webView = new WebView(this);
- ...
- webView.addJavascriptInterface(this, "contactSupport");
- ...
- }
- public void deleteContact(String contactId, String displayPage){
- ...
- }
下面的Javascript代碼則顯示了如何訪問(wèn)后端Java代碼ContactsActivity 對(duì)象實(shí)例中的deleteContact方法
- <script>
- ...
- function someJavaScriptFunction(){
- ..
- contactSupport.deleteContact(contactIdVar.val(),'ListPage.html');
- }
- ...
- </script>
Android Java代碼如何訪問(wèn)前端Javascript代碼
在本應(yīng)用中,我們使用WebView類中的loadUrl(String url)方法去實(shí)現(xiàn)兩個(gè)目的:
(1)在Webview瀏覽器中加載HTML頁(yè) (2) 在WebView中加載HTML時(shí),可以一道加載其中的Javascript。我們要注意如下兩點(diǎn):
◆在同一個(gè)容器頁(yè)面中,不同內(nèi)容頁(yè)之間的跳轉(zhuǎn),都使用Javascript代碼。
◆Transition from one container page to another is performed by Java code usingWebView.loadUrl(String url). The container page to display is passed to Java code from JavaScript as a callback parameter.
在不同的容器中的互相調(diào)用,需要在WebView的Java應(yīng)用程序中,通過(guò)使用
WebView.loadUrl(String url)去加載,下面這個(gè)圖講解了Java后端代碼如何訪問(wèn)前端Javascript代碼的步驟:
◆用戶首先訪問(wèn)HTML網(wǎng)頁(yè),這時(shí)調(diào)用Javascipt顯示頁(yè)面
◆接著,Javascript進(jìn)行一些數(shù)據(jù)的處理,并調(diào)用后端的Java代碼。
◆在Java代碼處理完后,會(huì)通過(guò)loadurl的方法,回調(diào)前端的Javascript代碼或者加載HTML頁(yè)。
下面的代碼,講解了前端的Javascript 代碼調(diào)用了后段的delteContact()方法后,刪除了數(shù)據(jù)庫(kù)中的記錄,然后會(huì)重新加載一個(gè)HTML頁(yè)進(jìn)行顯示。
- import android.webkit.WebView;
- import android.app.Activity;
- import android.os.Handler;
- ...
- public class ContactsActivity extends Activity {
- WebView webView;
- private Handler handler = null;
- ...
- public void onCreate(Bundle savedInstanceState) {
- ...
- webView = new WebView(this);
- ...
- handler = new Handler();
- ...
- }
- public void deleteContact(String contactId, String displayPage){
- ContactUtility.deleteContact(contactId,...);
- loadPage(displayPage);
- }
- public void loadPage(String in){
- final String url = "file:///android_asset/www/" + in;
- loadURL(url);
- }
- private void loadURL(final String in){
- handler.post(new Runnable() {
- public void run() {
- webView.loadUrl(in);
- }
- });
- }
這里,我們用到了Android中的Handler消息處理機(jī)制。本文不打算詳細(xì)講解Handler機(jī)制的用法,詳細(xì)的請(qǐng)參考Android手冊(cè)。這里簡(jiǎn)單提一下Handler消息處理機(jī)制,主要是在Android中,新啟動(dòng)的線程是無(wú)法刷新或者訪問(wèn)UI界面的,因此就要使用Handler機(jī)制。在這里,deleteContact()方法是無(wú)法直接調(diào)用 WebView.loadUrl()的,主要有兩個(gè)原因,一個(gè)是WebView實(shí)例是在onCreate方法中創(chuàng)建調(diào)用的,這是在主線程中;第二個(gè)原因是當(dāng)Javascript去調(diào)用deleteContact()時(shí),執(zhí)行它的線程實(shí)際上是跟ContactsActivity中的onCreate()方法中的主線程是不同的。因此,我們不難理解下面的三個(gè)步驟:
在deleteContac()中,我們刪除了某條通訊錄記錄。
接下來(lái),我們調(diào)用loadPage方法,這里我們指定了將要跳轉(zhuǎn)的顯示頁(yè)面,并在前面加了file:// android_asset/www/的前綴,意思是我們跳轉(zhuǎn)的這個(gè)頁(yè)面,實(shí)際上是存放在android_asset/www目錄下的。
Finally, we call the loadURL() method to have the Handler object call the WebView.***,我們?cè)趌oadURL方法中使用Handler機(jī)制的post,在新開的線程中加在WebView的loadUrl方法,并將其發(fā)送到消息隊(duì)列中去。#p#
如何調(diào)用前端的JavaScript
現(xiàn)在看下如何在后端的Java代碼中,調(diào)用前端的Javascript,代碼如下:
- public class ContactsActivity extends Activity {
- ...
- public void getAllContacts(String callback, String accountCallback){
- final String accountCallbackFunction = "javascript:" + accountCallback + "()";
- if(accountName == null){
- loadURL(accountCallbackFunction);
- return;
- }
- final String json = ContactUtility.getAllContactDisplaysJSON(getContentResolver());
- final String callbackFunction = "javascript:" + callback + "('" + json + "')";
- loadURL(callbackFunction);
- }
在上面的代碼中,getAllContacts方法作用是產(chǎn)生JSON格式的通訊錄列表,其結(jié)果存放在json變量中。然后再把結(jié)果回調(diào)給前端的javascript方法去處理解析JSON格式。這里
的callbackFunction = "javascript:" + callback + "(" + json + ")",通過(guò)javascript:前端處理的JAVASCRIPT方法名+JSON格式結(jié)果集,返回給前端。***也是通過(guò)loadURL方法,則可以達(dá)到調(diào)用前端Javascipt處理的效果。下面看前端Javscript代碼部分:
- <script>
- $(document).ready(function () {
- ...
- contactSupport.getAllContacts('setContactsList','showAccount');
- });
- </script>
在上面的代碼中,調(diào)用了Java后端的getAllContacts方法,而getAllContacts方法獲得JSON格式的結(jié)果集后,會(huì)調(diào)用前端Javascript的setContactsList方法去處理(這個(gè)方法具體內(nèi)容我們稍侯會(huì)介紹),而參數(shù)中的showAccount,則在后端的getAllContacts方法中,會(huì)判斷如果當(dāng)前通訊錄沒有任何數(shù)據(jù)時(shí),則會(huì)重新使用前端的showAccount這個(gè)JavaScript方法去處理。
在前后端交互中參數(shù)的類型問(wèn)題
在這個(gè)應(yīng)用中,我們?cè)谇昂蠖说慕换ブ校皇鞘褂昧俗址愋汀6渌愋腿鏘nteger等都將被轉(zhuǎn)型為字符串。而象復(fù)合類型的對(duì)象都將以JSON的形式進(jìn)行傳遞交互。在Java后端中,我們會(huì)使用Jackson JSON處理類庫(kù)對(duì)Java對(duì)象及JSON對(duì)象進(jìn)行轉(zhuǎn)換,在Javascript方面,則采用jQuery.parseJSON()方法去解析后端返回的JSON,在接下來(lái)的教程中,將會(huì)具體講解。
程序入口介紹
在我們的應(yīng)用中,ContactsActivity 是程序的主類,代碼如下:
- public class ContactsActivity extends Activity {
- WebView webView;
- private Handler handler = null;
- private String accountType = null;
- private String accountName = null;
- ...
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 初始化WebView
- webView = new WebView(this);
- setContentView(webView);
- //允許使用Javscript
- webView.getSettings().setJavaScriptEnabled(true);
- //檢查應(yīng)用中的帳號(hào)是否已經(jīng)建立
- accountType = "com.jquerymobile.demo.contact";
- Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
- if(accounts.length != 0){
- accountName = accounts[0].name;
- }
- handler = new Handler();
- webView.addJavascriptInterface(this, "contactSupport");
- // 裝載index.html頁(yè)
- loadPage("index.html");
- }
- ...
- }
代碼中關(guān)鍵點(diǎn)講解如下:
◆首先初始化WebView并允許Webview使用Javascript。
◆由于在前面已經(jīng)提到,通訊錄的使用必須關(guān)聯(lián)帳號(hào),所以這里使用android.accounts.AccountManager類去檢查應(yīng)用中是否已經(jīng)存在帳號(hào),如果存在的話,將帳號(hào)名稱賦值給變量accountName。
◆We initialize the handler field.接著使用handler機(jī)制,將ContactsActivity的對(duì)象實(shí)例和前端的Javascript綁定,交互的接口名稱為contactSupport。
index.html頁(yè)的代碼如下,其中,在jQuery的ready方法中,當(dāng)加載頁(yè)面完畢后,就開始加載ListPage.html了。
ListPage.html
首先講解的是ListPage.html代碼,其中回憶下前文提到的結(jié)構(gòu)圖,可以看到這個(gè)頁(yè)面容器包含了三個(gè)內(nèi)容頁(yè),分別是創(chuàng)建帳號(hào),通訊錄列表和進(jìn)度等待,代碼如下:
- <html>
- <head>
- <B><!-- jQuery Mobile Libraries --></B>
- <link rel="stylesheet" href="css-js/jquery.mobile-1.0a3.min.css" />
- <script src="css-js/jquery-1.5.min.js"></script>
- <script src="css-js/jquery.mobile-1.0a3.min.js"></script>
- </head>
- <body>
- <B><!-- Container Page --></B>
- <div data-role="page" data-theme="c" id="containerPage">
- <B><!-- Contact List --></B>
- <div data-role="header" id="hdrList" data-nobackbtn="true">
- <h1><img align="top" src="img/contacts.png"> Contacts</h1>
- <a id="buttonAddContact" data-icon="plus" class="ui-btn-right"
- href="<B>javascript:addContact();</B>return false;" data-role="button" data-inline="true">Add</a>
- </div>
- <div data-role="content" id="contentList" data-theme="c">
- <ul data-role="listview" data-dividertheme="c" id="contactSelections"></ul>
- </div>
- <div data-role="footer" id="ftrList"></div>
- <B><!-- Progress --></B>
- <div data-role="header" id="hdrProgress" data-nobackbtn="true" data-theme="c">
- <h1>Processing...</h1>
- </div>
- <div data-role="content" id="contentProgress" data-theme="c">
- <div align="CENTER"><h4>Please wait.</h4></div>
- <div align="CENTER"><img id="spin" src="img/wait.gif"/></div>
- </div>
- <div data-role="footer" id="ftrProgress" data-theme="c"></div>
- <B><!-- Create Account --></B>
- <div data-role="header" id="hdrAccount" data-nobackbtn="true" data-theme="c">
- <h1>Create Account</h1>
- </div>
- <div data-role="content" id="contentAccount" data-theme="c">
- <div align="CENTER"><img src="img/contacts-master-bgd.png"></div>
- <div align="CENTER"><h4>Please enter name of the new account for this application</h4></div>
- <div align="CENTER">Contacts created with this application will be associated with the new account specified below.
- Other contacts can be viewed, however, cannot be deleted or modified with this application.</div>
- <div align="CENTER" id="accountDiv" data-role="fieldcontain">
- <input id="accountName" type="text" />
- </div>
- <div align="CENTER">
- <a href="javascript:createAccount();return false;" <B>data-role="button"
- data-inline="true"</B>>Save</a>
- </div>
- ...
- </div>
- <div data-role="footer" id="ftrAccount" data-theme="c"></div>
- </div> <B><!-- Container Page Ends Here --></B>
- ...
#p#以上的代碼中,注意如下幾點(diǎn)
◆所有的三個(gè)內(nèi)容頁(yè)都有頁(yè)頭,頁(yè)腳和內(nèi)容區(qū)域。其中,每個(gè)部分都是用DIV層的方式去定義的,并且定義了data-theme=“c”,這個(gè)是使用了jQuery Mobile框架中預(yù)先定義好的顏色樣式,詳細(xì)的請(qǐng)參考jQuery Mobile手冊(cè)中的論述。
◆jQuery Mobile有預(yù)先定義好的返回按鈕,但我們將在應(yīng)用程序中去定義,因此這里并不需要,所以設(shè)置data-nobackbtn=“true”。
◆在“Contact List”的內(nèi)容頁(yè)中,有一個(gè)增加的按鈕,它是調(diào)用了addContact()方法,這個(gè)方法稍后會(huì)學(xué)習(xí)到。而id="contentList"的那個(gè)DIV中,實(shí)際上目前的內(nèi)容是空的,在程序中,會(huì)動(dòng)態(tài)把結(jié)果集填充到這里,另外請(qǐng)注意這里使用了jQuery Mobile中的listview樣式,表明這是一個(gè)列表的樣式。
◆注意在“Create Account”中的按鈕,其中用了data-incline=“true”,這表示按鈕的大小剛好是跟文字“Save”的大小相匹配的。
下面我們繼續(xù)分析ListPage.html。接下來(lái),我們看下如何實(shí)現(xiàn)同一個(gè)時(shí)間之顯示頁(yè)面容器中的某個(gè)頁(yè)面,比如我們?cè)谛陆◣ぬ?hào)時(shí),只希望顯示新建帳號(hào)的這個(gè)div。方法很簡(jiǎn)單,在jQuery的ready()方法中,將初始化一些變量,以保存頁(yè)面容器中的頁(yè)面,這通過(guò)jQuery中的$("#...")選擇器就可以實(shí)現(xiàn)了。然后,在需要顯示某個(gè)層的地方,定義hidePage()和showPage()方法,在這些方法中分別調(diào)用層的hide和show方法,就可以實(shí)現(xiàn)了。下面是例子,部分雷同的代碼省略,詳細(xì)見代碼下載:
- <script>
- var hdrListVar;
- var contentListVar;
- var ftrListVar;
- var hdrProgressVar;
- var contentProgressVar;
- var ftrProgressVar;
- var hdrAccountVar;
- var contentAccountVar;
- var ftrAccountVar;
- $(document).ready(function () {
- // Initialize commonly used variables
- hdrListVar = $('#hdrList');
- contentListVar = $('#contentList');
- ftrListVar = $('#ftrList');
- hdrProgressVar = $('#hdrProgress');
- contentProgressVar = $('#contentProgress');
- ftrProgressVar = $('#ftrProgress');
- hdrAccountVar = $('#hdrAccount');
- contentAccountVar = $('#contentAccount');
- ftrAccountVar = $('#ftrAccount');
- ...
- });
- ...
- function hideList(){
- hdrListVar.hide();
- contentListVar.hide();
- ftrListVar.hide();
- }
- function showList(){
- hideProgress();
- hideAccount();
- hdrListVar.show();
- contentListVar.show();
- ftrListVar.show();
- }
- function hideProgress(){
- hdrProgressVar.hide();
- contentProgressVar.hide();
- ftrProgressVar.hide();
- }
- ...
- </script>
接下來(lái),我們看下getAllContacts()方法,這個(gè)方法中,是獲得通訊錄列表,代碼如下:
- public void getAllContacts(String callback, String accountCallback){
- final String accountCallbackFunction = "javascript:" + accountCallback + "()";
- if(accountName == null){
- loadURL(accountCallbackFunction);
- return;
- }
- final String json = ContactUtility.getAllContactDisplaysJSON(getContentResolver());
- final String callbackFunction = "javascript:" + callback + "('" + json + "')";
- loadURL(callbackFunction);
- }
We had partially reviewed that code before. To recap:這段代碼之前已經(jīng)提到,其中我們著重看getAllContactDisplaysJSON方法,它會(huì)把后端的結(jié)果集取出,轉(zhuǎn)變?yōu)镴SON格式的字符串,然后回調(diào)到前端的Javascript中的方法去把JSON格式的數(shù)據(jù)重新整理。在我們的應(yīng)用中,是按字母表順序把聯(lián)系人的姓名進(jìn)行分組,下面我們來(lái)看其JSON格式的數(shù)據(jù)集,關(guān)于JSON本文不再詳細(xì)展開論述,請(qǐng)參考相關(guān)文檔。
- {"contacts":[
- {"key":"A","values":[
- {"contactId":"257","displayName":"Aach Herb","key":"A"},
- ...,
- {"contactId":"256","displayName":"Aaker David","key":"A"}
- ]
- },
- {"key":"B","values":[
- {"contactId":"259","displayName":"Belanger Andre","key":"B"},
- ...,
- {"contactId":"260","displayName":"Bohme Jacob","key":"B"}
- ]
- },
- ...
- ]
- }
可以看到,其中按字母表順序進(jìn)行了分組,key屬性代表的是字母,values的值是一個(gè)JSON格式的數(shù)組,包含的是每個(gè)字母下的聯(lián)系人的具體通訊錄。
接下來(lái),我們看下前端頁(yè)面的Javascript如何解析后端傳送過(guò)來(lái)的JSON格式的字符串。代碼如下:
- <div data-role="content" id="contentList" data-theme="c">
- <ul data-role="listview" data-dividertheme="c" id="contactSelections"></ul>
- </div>
- ...
- <script>
- ...
- // Commonly used variables
- ...
- var contactSelectionsVar;
- $(document).ready(function () {
- // Initialize commonly used variables
- ...
- contactSelectionsVar = $('#contactSelections');
- ...
- }
- ...
- function setContactsList(jsonText){
- var tmpJson = $.parseJSON(jsonText);
- if(tmpJson != null && tmpJson.contacts != null){
- var tmpContacts = tmpJson.contacts;
- for(i = 0; i < tmpContacts.length; i++){
- var tmpKey = (tmpContacts[i]).key;
- var tmpKeyFragment = '<li data-role="list-divider">'+tmpKey+'</li>';
- contactSelectionsVar.append(tmpKeyFragment);
- var tmpValues = (tmpContacts[i]).values;
- if(tmpValues != null){
- var j;
- for(j = 0; j < tmpValues.length; j++){
- var tmpDisplayName = tmpValues[j].displayName;
- var tmpContactId = tmpValues[j].contactId;
- var tmpLiFragment = '<li><a href="javascript:showContact(' +
- tmpContactId + ');return false;">'+tmpDisplayName+'</a></li>';
- contactSelectionsVar.append(tmpLiFragment);
- }
- }
- }
- }
- contactSelectionsVar.listview('refresh');
- showList();
- }
- ...
- </script>
◆首先,利用了jQuery的parseJSON方法,去解析后端獲得的JSON格式代碼,解析后的賦值給tmpJson變量。
然后,使用var tmpContacts = tmpJson.contacts;一句,獲得了前文提到的JSON格式中的CONTACTS部分的內(nèi)容,然后再使用一個(gè)FOR循環(huán),在循環(huán)體內(nèi),每次通過(guò)
var tmpKey = (tmpContacts[i]).key,獲得的JSON字符串中的key部分(即每個(gè)字母),
◆然后將tmpKey變量與組合成變量tmpKeyFragment。其是jQuery Mobile中的列表項(xiàng)目分割符號(hào)。
◆.再將tmpKeyFragment變量,使用jQuery的append方法添加到contactSelectionsVar這個(gè)DIV區(qū)域中。
◆接下來(lái)的這步,是先讀取JSON字符串中的values屬性中的值,變量tmpValues存放的就是每個(gè)字母下的所有通訊錄聯(lián)系人列表,然后使用循環(huán)去讀取每個(gè)聯(lián)系人的contactId和displayName。
再把tmpDisplayName和 tmpContactId組合成tmpLiFragment變量,注意這里加入了一個(gè)鏈接",其目的是當(dāng)用戶點(diǎn)這個(gè)聯(lián)系人的名稱時(shí),會(huì)用javascript調(diào)出另外的顯示詳細(xì)信息的頁(yè)面。同樣,***我們將其添加到contactSelectionsVar這個(gè)div層中。
◆***,我們使用contactSelectionsVar.listview的refresh方法,更新列表。
下圖是該部分代碼跟實(shí)際效果的對(duì)應(yīng)圖,可以清楚看到兩者間的結(jié)構(gòu):
小結(jié)
在本系列教程的***篇,我們介紹了將要設(shè)計(jì)的應(yīng)用的概況,頁(yè)面結(jié)構(gòu)和jQuery Mobile框架中頁(yè)面的一些元素知識(shí),也介紹了Android中的后端JAVA程序如何跟前端的Javascript進(jìn)行互相數(shù)據(jù)交互的基本知識(shí)。在下篇教程中,我們將學(xué)習(xí)如何新建立一個(gè)通訊錄的帳號(hào),以及如何對(duì)通訊錄列表進(jìn)行增刪改。