Jquery Mobile设计Android通讯录第二章
本文是jQuery Mobile設計Android通訊錄系統教程的第二篇,在上一篇教程中(http://publish.itpub.net/a2011/0517/1191/000001191561.shtml), 初步介紹了我們要設計的應用的架構和頁面結構,并介紹了Jquery Mobile框架中重要的頁面元素的知識,以及Android JAVA應用程序如何跟前端的Javascript頁面進行交互。在本系列教程的第二篇,將介紹如何創建新的通訊錄帳號及如何修改和刪除已經存在的通訊錄 名單。
創建通訊錄帳號
下面來看下如何新創建通訊錄帳號。用戶只需要輸入自己的姓名,點保存按鈕。其中該部分的代碼是在ListPage.html中可以找到,代碼如下:
<html> ??... <body><!-- Container Page --><div data-role="page" data-theme="c" id="containerPage"> ??... ??<!--??Create Account --> ??<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;" data-role="button" ????????data-inline="true">Save</a> ????</div> ????... ??</div> ??<div data-role="footer" id="ftrAccount"??data-theme="c"></div></div><!-- Container Page Ends Here --> ... <script> ... ??function createAccount(){ ????showProgress(); ????contactSupport.createAccount($('#accountName').val(),'ListPage.html');??} ??... </script>
· 我們把創建帳號這個頁面放在頁面容器中,這個頁面有自己的頭部,內容content部分和頁腳部分。
· 當點SAVE按鈕時,將會調用Javasccript中的createAccount()方法。
· 在Javasccript中的createAccount()方法中,獲得用戶的輸入的帳號名,即使用
'#accountName').val()獲得其值,然后通過調用后端Android Java應用中的createAccount方法去保存帳戶名。跟后端Android Java的交互,在本系列的第一篇教程中有提到,如果不大清楚,請查看第一篇教程。
下面看下后端的Android Java應用中的createAccount方法如何編寫。
import android.accounts.AccountManager; import android.accounts.Account; ... public class ContactsActivity extends Activity { ??... ??privateString accountType =null; ??... ??public void onCreate(Bundle savedInstanceState) { ????... ????accountType ="com.jquerymobile.demo.contact"; ????... ??}??public void createAccount(String accountN, String displayPage){ ????if(accountN !=null&& !"".equals(accountN)){ ??????accountName = accountN; ??????AccountManager.get(this).addAccountExplicitly(new Account(accountName,accountType), "dummyPassword", null); ????} ????loadPage(displayPage); ??} ??... }
下面講解下這段代碼:
· 實際上帳號的創建是通過android.accounts.AccountManager類去創建的。Android2.0中加入了一個新的包 android.accounts,該包主要包括了集中式的賬戶管理API,用以安全地存儲和訪問認證的令牌和密碼,比如,我們的手機存在多個賬戶,每個賬戶下面都有不同的信息,甚至每個賬戶都可以與不同的服務器之間進行數據同步(例如,手機賬戶中的聯系人可以是一個Gmail賬戶中的通訊錄,可聯網進行同步更新)。
這里首先通過AccountManager.get()獲得了它的一個實例,接著調用其addAccountExplicitly方法,創建了一個新的 帳號,和密碼(這里的密碼默認是dummyPassword),當帳號創建完后,將回調HTML頁面,這里通過loadPage方法去加載回調HTML頁 面。
.為了能調用Android API中的創建帳號的功能,必須在
AndroidManifest.xml中進行如下設置,聲明一個intent-filter:
<intent-filter> ??<action android:name="android.accounts.AccountAuthenticator"/></intent-filter>.除此之外,必須在meta-data中聲明帳號驗證器如下:
<meta-data ??android:name="android.accounts.AccountAuthenticator" ??android:resource="@xml/authenticator"/>Finally, the res/xml/authenticator.xml configuration file (which is value of the android:resourceattribute above) should have an element named account-authenticator where value ofandroid:accountType attribute issetto com.jquerymobile.demo.contact. Note that this is value of theaccountType in ContactsActivity. Summarizing the discussion, first look at the highlighted section inAndroidManifest.xml. 這里,用android:resource的值,指出了要在res/xml下配置一個驗證配置文件authenticator.xml,文件如下:
<?xml version="1.0" encoding="utf-8"?><account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" ??android:accountType="com.jquerymobile.demo.contact" ??android:icon="@drawable/icon" ??android:smallIcon="@drawable/icon" ??android:label="@string/app_name"/>
其中的android:accountType指出了要驗證的帳號的實體類為com.jquerymobile.demo.contact。最后我們綜合看下修改后的AndroidManifest.xml如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" ??package="com.jquerymobile.demo.contact" ??android:versionCode="1" ??android:versionName="1.0"> ????<uses-permission android:name="android.permission.READ_CONTACTS"/> ????<uses-permission android:name="android.permission.WRITE_CONTACTS"/> ????<uses-permission android:name="android.permission.GET_ACCOUNTS"/> ????<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> ????<application android:debuggable="true" android:icon="@drawable/icon" ??????android:label="@string/app_name"> ????????<service ??????????android:name=".authentication.AuthenticationService" ??????????android:exported="true"> ??????????<intent-filter> ????????????<action android:name="android.accounts.AccountAuthenticator"/> ????????????</intent-filter> ????????????<meta-data android:name="android.accounts.AccountAuthenticator" ??????????????android:resource="@xml/authenticator"/> ????????</service> ????????<activity android:name=".ContactsActivity" ??????????android:configChanges="orientation|keyboardHidden" ??????????android:label="@string/app_name"> ????????????<intent-filter> ??????????????<action android:name="android.intent.action.MAIN"/> ??????????????<category android:name="android.intent.category.LAUNCHER"/> ????????????</intent-filter> ????????</activity> ????</application></manifest>??在文件中用uses-permission分別設置了帳號的讀寫或校驗的權限,并且聲明了帳號的管理服務實現類為 com.jquerymobile.demo.contact. authentication.AuthenticationService,在這個類中,將編寫一些關于帳號管理操作的業務邏輯。這個帳號業務管理器被 定義為Android中的一個服務,代碼如下:
package com.jquerymobile.demo.contact.authentication;import android.app.Service; import android.content.Intent; import android.os.IBinder;
public class AuthenticationService extends Service { ??public IBinder onBind(Intent intent) { ????return null; ??} }
可以看到,這里跟普通的編寫Android服務沒什么大的區別,這里在onBind()中并沒有編寫具體的代碼,只是返回了null。但如果你需要將創 建的帳號跟一些在線服務結合起來,那么則需要在這里編寫相關的實現代碼,并且還需要實現 android.accounts.AbstractAccountAuthenticator接口。這里我們足夠用了,所以返回null。現在,運行程 序,在輸入帳號并保存后,你會發現在Android 手機中
的Accounts and sync settings的選項設置中,會發現你剛才新建的帳號,如下圖所示:
▲
列出已存在的通訊錄
下面,我們看下,當用戶點某個人名的通訊錄時,會顯示其通訊錄的詳細情況。先回顧下在本系列教程第一篇中,提到的如下代碼:
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(); ??}這里,通過javascript去調用了showContact方法,用于顯示某個人的具體通訊錄,代碼如下:
function showContact(tmpId){ ??showProgress(); ??contactSupport.showContact(tmpId,'DetailPage.html');}這里,首先調用了等待圖標的顯示方法,然后同樣調用后端Android Java的showContact方法調出通訊錄的詳細信息,然后再把結果回調顯示到DetailPage.html中
而后端JAVA對應的showContact方法如下:
public void showContact(String contactId, String displayPage){ ??loadPage(displayPage +"?"+ contactId); }這里再通過loadPage調用前端的Javscirpt頁面,并傳入要查看的通訊錄的參數contactId,假如現在要看的某人的通訊錄的 contatId是23,而回顯通訊錄詳細信息的頁面是DetailPage.html,則跳轉的URL為DetailPage.html?23
通訊錄詳細信息頁
.通訊錄詳細信息頁Detail.html頁面代碼如下,它分為三個部分,分別是顯示已存在的詳細通訊錄信息頁,空白的用于新建顯示錄入通訊錄的信息頁以及在刪除通訊錄時顯示的界面,先來看顯示已存在的詳細通訊錄信息頁的代碼如下:
<div data-role="page" data-theme="c" id="containerPage"> ??<!-- Header for contact details --> ??<div data-role="header" id="hdrDetail" data-nobackbtn="true" data-theme="c"> ????<h1><img align="top"??src="img/contacts.png"> Details</h1> ??</div>??<div data-role="content" id="contentDetail" data-theme="c"> ????<form id="contactForm" onsubmit="return false;"> ??????<input id="contactId" type="hidden">
??????<div id="namesDiv" data-role="fieldcontain"> ????????<table> ??????????<tbody> ????????????<tr> ??????????????<td>First name</td> ??????????????<td><input id="firstName" type="text"></td> ????????????</tr> ????????????<tr> ??????????????<td>Last<br> ????????????????name</td> ??????????????<td><input id="lastName" type="text"></td> ????????????</tr> ????????????<tr> ??????????????<td>Notes</td> ??????????????<td><input id="note" type="text"></td> ????????????</tr> ??????????</tbody> ????????</table> ??????</div>
??????<div data-role="collapsible" data-collapsed="true"> ????????<h3>Phone Numbers</h3> ????????<table id="phonesTable"></table> ??????</div>
注意如下幾點:
· 這里的contactId是一個隱藏域,記錄當前查看或修改的通訊錄的ID號,在更新時必須用到。
· 這里的電話號碼是一個可以展開輸入的伸縮面板,使用的是
jQuery Mobile框架中的可伸縮區塊的方法(具體參考:http://jquerymobile.com/demos/1.0a3/#docs /content/content-collapsible.html)。這里,為方便用戶輸入電話提供了更多的輸入選項,當用戶點“Phone Number”時,會下拉顯示出更多的四種不同的通訊方式以供用戶輸入。只需要在代碼中寫入data-role="collapsible" data-collapsed="true"兩個jQuery Mobile的屬性即可。實際效果如下圖:
我們繼續來看,剩下的象EMAIL及“更多”部分,都同樣使用了jQuery Mobile中的可收縮區域的技術去實現,具體代碼請參考附件,這里不再列出,下面是其中的幾個截圖如下:
▲
最后是顯示三個新增,修改及刪除的按鈕及頁面的底部,代碼如下:
<div align="CENTER" data-role="controlgroup" data-type="horizontal"> ??????<a href="javascript:generateJson();return false;" data-role="button"><h5>Save</h5></a> ??????<a id="deleteButton"??href="javascript:showDialog();return false;" data-role="button"??><h5>Delete</h5></a> ??????<a href="javascript:showListPage();return false;" data-role="button"><h5>Cancel</h5></a> ????</div> ??</div>??<!-- Footer for contact details --> ??<div data-role="footer" id="ftrDetail" data-theme="c"></div> ... </div><!-- Container page -->
· 注意這里使用了data-role="controlgroup"這一jQuery Mobile提供的屬性,將三個按鈕都以同一分組的形式放在同一個區域,而data-type="horizontal" 則表示以垂直的方式分組將按鈕進行擺放設置。
· 三個按鈕都通過Javascript實現觸發。
接下來是顯示進度條等待的頁面,代碼如下,比較簡單,不詳細論述。
<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 alt="" id="spin" src="img/wait.gif"> ??</div></div>
<div data-role="footer" id="ftrProgress" data-theme="c"></div>
當用戶要刪除某條通訊錄時,會出現新的頁面,以詢問用戶是否確認刪除,代碼如下:
<div data-role="header" id="hdrDialog" data-nobackbtn="true" data-theme="c"> ??<h1>Confirm delete</h1></div><div data-role="content" id="contentDialog"??data-theme="c"> ??<div align="CENTER"> ????<h4>Are you sure you want to delete this contact?</h4> ??</div> ??<div align="CENTER" data-role="controlgroup" data-type="horizontal"> ????<a href="javascript:deleteContact();return false;" data-role="button"><h5>Delete</h5></a> ????<a href="javascript:showDetail();return false;" data-role="button"><h5>Cancel</h5></a> ??</div></div>
<div data-role="footer" id="ftrDialog" data-theme="c"></div>
用Javascript控制頁面的顯示和隱藏
在本教程的第一講中,已經講解了如何通過jQuery及Javscript,控制一個頁面容器中各個容器子頁的顯示和隱藏,這里只是簡單提到復習下,詳 細的請參考第一篇教程。我們可以在jQuery的ready()方法中,定義一系列的變量,分別指代頁面容器中各子頁的頭部,內容部分和頁腳部分,然后由 于各個部分其實都是div層的結構,所以顯示時只需要調用show方法即可,隱藏時調用hide方法即可,下面是部分代碼,具體代碼請參考下載附件:
<script> ??... ??//定義變量 ??var contactIdVar;??<!-- contact details --> ??var hdrDetailVar; ??var contentDetailVar; ??var ftrDetailVar;
??$(document).ready(function () { ?????? contactIdVar = $('#contactId'); ????<!-- contact details --> ????hdrDetailVar = $('#hdrDetail');????contentDetailVar = $('#contentDetail');????ftrDetailVar = $('#ftrDetail'); ??????... ??}?? ??function hideDetail(){ ????hdrDetailVar.hide(); ????contentDetailVar.hide(); ????ftrDetailVar.hide(); ??}
??function showDetail(){ ????hideDialog(); ????hideProgress(); ????hdrDetailVar.show(); ????contentDetailVar.show(); ????ftrDetailVar.show(); ??}??
</script>
顯示已存在的數據記錄
Having reviewed the structure of content pages in DetailPage.html, let us look into how to populate the contact details for an existing contact. Recall that the ContactsActivity.showContact() method displays DetailPage.html appending id of the contact as an HTTP query string, e.g. DetailPage.html?23. Let us see below how JavaScript code in DetailPage.html will process that information. The related section in jQuery $(document).ready() function is given below.
在知道了頁面結構后,我們 現在看下,如何將后端的數據顯示在前端的界面中,這樣當用戶點選一個已存在的通訊錄時,會把該通訊錄的詳細信息顯示出來。我們看下之前說的,舉例說到的 DetailPage.html?23這樣方式的鏈接,看下在DetailPage.html中,是如何用Javascript去讀取后端的數據的,關鍵 是看jQuery中的ready()方法中處理的代碼,如下:
$(document).ready(function () { ??... ??showProgress(); ??contactIdVar.val(window.location.search.substring(1)); ??contactSupport.getContact(contactIdVar.val(),'setCurrentContact');});· 首先是加載了進度等待圖標
· 然后用window.location.search.substring(1)獲得了當前鏈接的中?號后的參數,比如對于DetailPage.html?23這個例子來說,獲得了23的值,并且賦值給 contactIdVar.val這個變量。
· 最后,通過調用后端JAVA應用的ContactsActivity.getContact()方法,傳入的是兩個參數,一個是當前通訊錄的id,另外的 setCurrentContact是回調前端顯示處理結果的Javascript方法。下面看下 ContactsActivity.getContact()方法的實現,如下:
public void getContact(String contactId, String contactCallback){ ??String json = ContactUtility.getContactJSON(contactId, ...); ??final String callbackFunction ="javascript:"+ contactCallback +"('"+ json +"')"; ??loadURL(callbackFunction); }這里,通過getContactJSON方法,產生了JSON格式的數據。下面看下如何產生JSON格式的數據。下面是應用中模擬生成的JSON代碼,代碼如下:
{ ??"contactId":"265", ??"firstName":"Aafjes", ??"lastName":"Bertus", ??"note":{"rowId":"2265","text":"Author"}, ??"ims":[ ????{"rowId":"2274","protocol":"-1","value":""}, ????{"rowId":"2275","protocol":"0","value":"bertus@aim"}, ????{"rowId":"2276","protocol":"5","value":"bertus@google"}, ????{"rowId":"2277","protocol":"6","value":""}, ?? 。。。。。。。 ??], ??"phones":[ ????{"rowId":"2284","type":"1","no":"111-222-3333"}, ????{"rowId":"2285","type":"2","no":"222-000-9999"}, ????{"rowId":"2286","type":"3","no":"444-787-9900"}, ????{"rowId":"2287","type":"7","no":"555-744-9999"} ??], ??"emails":[ ????{"rowId":"2271","type":"1","value":"bertus@home.xyz"}, ????{"rowId":"2272","type":"2","value":"bertus@work.xyz"}, ????{"rowId":"2273","type":"3","value":"bertus@other.xyz"} ??], ??"organizations":[ ????{"rowId":"2269","type":"1","name":"Publications Inc.","title":"CEO"}, ????{"rowId":"2270","type":"2","name":"Volunteers Corp.","title":"Member"} ??], ??"addresses":[ ????{"rowId":"2266","type":"1","street":"Alhambra st.","city":"Alhambra","state":"MI", ??????"country":"USA","zip":"48100","poBox":""}, ????{"rowId":"2267","type":"2","street":"1 Corporation st","city":"Alhambra","state":"MI", ??????"country":"USA","zip":"48000","poBox":"44456"}, ????{"rowId":"2268","type":"3","street":"","city":"","state":"", ??????"country":"","zip":"","poBox":""} ??] }以上的JSON中,contactId, firstName, lastName都是字符串類型,而address,email,phones等都是每個JSON對象中包含了多個對象,形成一個JSON數組。
· 注意在以上的對象中,都有一個rowId,它都是不會重復的,用以區別不同的記錄,也方便在前端Javascript代碼中進行處理。
· 在ims數組中,有protocol屬性,它代表是用戶使用哪種即時通訊工具,這是由Android 通訊錄 API給出的定義,定義如下:
o protocol=-1, 自定義
o protocol=0, AIM
o protocol=1, MSN
o protocol=2, Yahoo
o protocol=3, Skype
o protocol=4, QQ
o protocol=5, Google
o protocol=6, ICQ
o protocol=7, Jabber
· 同樣,在phones數組中的type屬性,也是Android 通訊錄 API給出的定義,如下:
o type=1, Home
o type=2, Mobile
o type=3, Work
o type=7, Other
· emails數組中的type屬性,API定義如下:
o type=1, Home
o type=2, Work
o type=3, Other
· organizations 數組中的type屬性定義如下:
o type=1, Work
o type=2, Other
· addresses 數組中的type屬性定義如下:
o type=1, Home
o type=2, Work
o type=3, Other
在Javascript中解析JSON
下面我們看下如何在Javascript中對JSON進行解析。
定義常量
我們為了設計方便,在Javscirpt中先定義一些常量,以方便代碼的書寫和閱讀,代碼如下:
<script> ??// Constants ??var STYLED_IN ='<input type="text" class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" id="';??var TR_O ='<tr><td>';??var TD_C ='</td></tr>';??var TD_M ='</td><td>';??var VALUE =' value="'; ??var WORK_ORG_FRAGMENT_SFX ='">'+TD_C; ??var HOME_FRAGMENT_PRX = TR_O+'Home'+TD_M+STYLED_IN;??var MOBILE_FRAGMENT_PRX = TR_O+'Mobile'+TD_M+STYLED_IN;??var WORK_FRAGMENT_PRX = TR_O+'Work'+TD_M+STYLED_IN;??var OTHER_FRAGMENT_PRX = TR_O+'Other'+TD_M+STYLED_IN; ??var HOME_PHONE_FRAGMENT_MID ='_1_No"' + VALUE;??var MOBILE_PHONE_FRAGMENT_MID ='_2_No"' + VALUE;??var WORK_PHONE_FRAGMENT_MID ='_3_No"' + VALUE;??var OTHER_PHONE_FRAGMENT_MID ='_7_No"' + VALUE;??...以上要注意的是在變量 STYLED_IN中,增加了jQuery Mobile中特定的樣式。jQuery Mobile允許動態向一個表中增加行,但我們發現目前的版本,在動態增加行后,jQuery Mobile并沒有將上一層的<div>標記中的樣式自動應用到<input>中去,所以要另外增加。
定義一些變量
下面定義一些初始變量,并進行初始化。
<script> ??... ??var currentContact; ??var firstNameVar; ??var lastNameVar; ??var noteVar; ??var contactIdVar; ??var phonesTableVar; ??... ??$(document).ready(function () { ????firstNameVar = $('#firstName');????lastNameVar = $('#lastName');????noteVar = $('#note');????contactIdVar = $('#contactId');????phonesTableVar = $('#phonesTable');????... ??}接下來,我們使用jQuery的parseJSON功能去解析后端程序返回的JSON字符串,其中用變量 currentContact保存JSON字符串,而contactId, firstName, lastName和note則可以直接從JSON中解析出來,比較簡單,如下所示:
function setCurrentContact(jsonText){ ????currentContact = $.parseJSON(jsonText); ????contactIdVar.val(currentContact.contactId); ????firstNameVar.val(currentContact.firstName); ????lastNameVar.val(currentContact.lastName); noteVar.val(currentContact.note.text);解析對象數組
接下來,我們看下如何解析象Phone,Email,Address這些對象數組類型的JSON元素。這里其實只需要用循環對JSON中的 Phone,Email,Address分別進行遍歷,然后再用變量保存即可,下面以Phone為例進行說明,分別用 tmpType, tmpRowId, tmpNo保存了解析出來的type,rowId和no。
??var phonesArr = currentContact.phones; ????...????????if(phonesArr !==null){ ??????for(i =0; i < phonesArr.length; i++){ ????????var tmpType = (phonesArr[i]).type; ????????var tmpRowId = (phonesArr[i]).rowId; ????????var tmpNo = (phonesArr[i]).no; ????????...
根據不同的電話類型,我們構建了對應的HTML片斷去展示JSON解析出來的電話號碼,比如如果是家庭號碼,并且tmpRowId為15和值是222333444,則以如下形式展示:
HOME_FRAGMENT_PRX + tmpRowId + HOME_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX
這實際上出來的效果是如下的HTML代碼:
<tr><td>Home</td><td><input type="text" ??class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" ??id="15_1_No" value="2223334444"></td></tr>最后,我們綜合來看下解析JSON字符串的代碼中,其中Phone部分的展示方法如下:
var mobilePhoneSet =false; var homePhoneSet =false; var workPhoneSet =false; var otherPhoneSet =false;??????????if(phonesArr !==null){ ??for(i =0; i < phonesArr.length; i++){ ????????var tmpType = (phonesArr[i]).type; ????????var tmpRowId = (phonesArr[i]).rowId; ????????var tmpNo = (phonesArr[i]).no;
????if(tmpType ==1){//home ??????phonesTableVar.append(HOME_FRAGMENT_PRX + tmpRowId + HOME_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX); ??????homePhoneSet =true; ????}elseif(tmpType ==2){//mobile ??????phonesTableVar.append(MOBILE_FRAGMENT_PRX + tmpRowId + MOBILE_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX); ??????mobilePhoneSet =true; ????}elseif(tmpType ==3){//work ??????phonesTableVar.append(WORK_FRAGMENT_PRX + tmpRowId + WORK_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX); ??????workPhoneSet =true; ????}elseif(tmpType ==7){//other ??????phonesTableVar.append(OTHER_FRAGMENT_PRX + tmpRowId + OTHER_PHONE_FRAGMENT_MID + tmpNo + FRAGMENT_SFX); ??????otherPhoneSet =true; ????} ??} }
要注意的是,假如通訊錄中有的聯系人并沒有所有的電話類型(比如只有工作電話,而沒記載家庭電話),則需要用如下代碼:
var HOME_PHONE_FRAGMENT_LOCAL = TR_O+'Home'+TD_M+STYLED_IN+'-1_1_No">'+TD_C;??var MOBILE_PHONE_FRAGMENT_LOCAL = TR_O+'Mobile'+TD_M+STYLED_IN+'-1_2_No">'+TD_C;??var WORK_PHONE_FRAGMENT_LOCAL = TR_O+'Work'+TD_M+STYLED_IN+'-1_3_No">'+TD_C;??var OTHER_PHONE_FRAGMENT_LOCAL = TR_O+'Other'+TD_M+STYLED_IN+'-1_7_No">'+TD_C;??... ??if(phonesArr !==null){ ????... ??} ??if(!homePhoneSet){ ????phonesTableVar.append(HOME_PHONE_FRAGMENT_LOCAL); ??} ??if(!mobilePhoneSet){ ????phonesTableVar.append(MOBILE_PHONE_FRAGMENT_LOCAL); ??} ??if(!workPhoneSet){ ????phonesTableVar.append(WORK_PHONE_FRAGMENT_LOCAL); ??} ??if(!otherPhoneSet){ ????phonesTableVar.append(OTHER_PHONE_FRAGMENT_LOCAL); ??}解析下上面這段代碼,假設某個聯系人沒工作移動電話,那么 workPhoneSet 為false,上面的代碼會變為:
<tr><td>Home</td><td><input type="text" ????class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c" id="-1_1_No"></td></tr>這實際上是向DIV區域加了一個空白的文本域而已。
最后,當解析完后端返回的JSON字符串后,就在 setCurrentContact最后,調用showDetail()方法,顯示出內容頁面即可
??function setCurrentContact(jsonText){ ????... ????showDetail(); ??}最后,總結下顯示已存在的通訊錄的頁面流向和步驟,如下:
ContactsActivity.loadPage('DetailPage.html?id')??-> DetailPage.html:$(document).ready() ????-> ContactsActivity.getContact(id, 'setCurrentContact')??????->??DetailPage.html:setCurrentContact(json)刪除一條通訊錄
當用戶點刪除按鈕時,代碼如下:
function deleteContact(){ ??showProgress(); ??contactSupport.deleteContact(contactIdVar.val(),'ListPage.html');}?
這里同樣也是調用后端JAVA應用的deleteContact方法,并且向后端傳入要刪除的當前通訊錄的ID。而后端的代碼如下:
public void deleteContact(String contactId, String displayPage){ ??ContactUtility.deleteContact(contactId, ...); ??loadPage(displayPage); }?
其中這里的ContactUtility.deleteContact方法,將會在后續的教程中詳細講解。
保存通訊錄
在保存已經寫好的通訊錄后,當用戶點保存按鈕時,將會將用戶的輸入產生為JSON格式,然后提交到后端去,代碼如下:
function generateJson(){ ??showProgress(); ??var jsonText ='{';??jsonText +='"contactId":"' + contactIdVar.val() + '"';??jsonText +=',"firstName":"' + firstNameVar.val() + '"';??jsonText +=',"lastName":"' + lastNameVar.val() + '"';??jsonText +=',"note":{"rowId":"","text":"' + noteVar.val() + '"}';??...???
可以看到,實際上就是將用戶的輸入組織為JSON格式的字符串,注意,其中note中的rowId這里可以設置為空字符串,因為對于新增記錄來說,這個字段并不重要。
下面是對電話phones字段的保存代碼,如下:
// Phones ??jsonText +=',"phones":[';??$('input[id$="_No"]').each(function(index) {????jsonText +='{"rowId":"","type":"';????jsonText += (($(this).attr('id')).split('_'))[1] + '","no":"';????jsonText += $(this).attr('value') + '"';????jsonText +='},';??}); ??jsonText = addClosingBracket(jsonText); ??... ??jsonText +='}';??contactSupport.saveContact(jsonText,'ListPage.html');}????????????function addClosingBracket(txt){ ??if((txt.length -1) == txt.lastIndexOf(',')){????txt = txt.substring(0,txt.length -1) +']';??}else{ ????txt +=']';??} ??return txt; }
?
對于電話類型type,這里要將用戶的輸入進行截取,比如id="15_1_No",則電話類型為1,
這里做了一個簡單對所有的<input>元素進行分析截取。
當準備好要向后端提交的JSON格式后,則可以調用后端JAVA應用的ContactsActivity.saveContact()方法進行保存,代碼如下:
import org.codehaus.jackson.map.ObjectMapper;public class ContactsActivity extends Activity { ??... ??public void saveContact(String json, String displayPage){ ????ObjectMapper mapper =new ObjectMapper(); ????try{ ??????Contact c = mapper.readValue(json,Contact.class); ????????ContactUtility.saveOrUpdateContact(c, getContentResolver(), accountName, accountType); ????}catch(Exception e){ ??????... ????} ????loadPage(displayPage); ??} ??... }
?
其中ObjectMapper類是Jackson JSON解析處理器中的一個負責將JSON轉化為POJO實體類的工具類。Jackson JSON(http://jackson.codehaus.org/)是個不錯的JSON分析處理工具。其使用很簡單,這里通過 mapper.readValue(json,Contact.class);
就完成了將JSON字符串解析轉為Contract實體類的工作,最后用saveContact()方法進行保存。
小結
在本系列教程的第二篇,討論了如何讀取和編輯存在的通訊記錄到前端頁面,如何新建通訊錄的帳號。在下一篇教程中,將討論使用Android API去訪問通訊錄中的相關數據。
轉載于:https://www.cnblogs.com/huidaoli/p/3549767.html
總結
以上是生活随笔為你收集整理的Jquery Mobile设计Android通讯录第二章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求1-100之间的奇数和、偶数和
- 下一篇: PHP校验ISBN码的函数