36 APP常用功能設(shè)計(jì)
啟動(dòng)頁(yè)面的圖片設(shè)計(jì)成動(dòng)態(tài)配置的,可以顯示不同的廣告。
當(dāng)服務(wù)器更新了顯示的圖片后,APP下載并保存到本地,下次啟動(dòng)的時(shí)候顯示新圖片。
在啟動(dòng)APP的時(shí)候,因?yàn)橐ㄙM(fèi)時(shí)間解析布局文件和加載資源,導(dǎo)致會(huì)出現(xiàn)短暫的白屏現(xiàn)象。
解決方案如下:
//先定義style
parent="Android:style/Theme.Black.NoTitleBar.Fullscreen">
@drawable/img_launcher
//設(shè)置啟動(dòng)Activity的theme為之前定義的style
android:name=".ui.MainActivity"
android:noHistory="true"
android:screenOrientation="portrait"
android:theme="@style/AppSplash">
首頁(yè)顯示的內(nèi)容比較多,如果APP只發(fā)一次請(qǐng)求,服務(wù)器端把所有的數(shù)據(jù)等準(zhǔn)備好后,一次性返回,勢(shì)必導(dǎo)致等待的時(shí)間比較長(zhǎng)。
可以設(shè)計(jì)成調(diào)用多個(gè)接口從服務(wù)器返回?cái)?shù)據(jù),這樣只要有一個(gè)接口返回?cái)?shù)據(jù)了,就顯示在頁(yè)面上,避免用戶長(zhǎng)時(shí)間的看到空白頁(yè)面。
調(diào)用多個(gè)接口的時(shí)候,如果有一個(gè)接口遇到連接超時(shí)之類的錯(cuò)誤,那就自動(dòng)取消其余接口請(qǐng)求。
首頁(yè)一定要做緩存處理,無(wú)網(wǎng)絡(luò)或緩存數(shù)據(jù)在有效期時(shí),讀取緩存中的數(shù)據(jù),減少用戶的等待時(shí)間。
首頁(yè)不要顯示銷量和庫(kù)存等實(shí)時(shí)會(huì)變化的數(shù)據(jù),這樣就沒(méi)法做緩存處理了。
首頁(yè)通常都用輪播圖展示,在退出首頁(yè)時(shí),務(wù)必要關(guān)閉輪播定時(shí)器。
首頁(yè)通常有多個(gè)TAB頁(yè),具體代碼實(shí)現(xiàn)可以采用單個(gè)Activity+多個(gè)Fragment的方式。
登錄功能的使用有兩種場(chǎng)景:
1 A頁(yè)面點(diǎn)擊按鈕,顯示登錄界面,登錄后,還是停留在A頁(yè)面,但A頁(yè)面顯示的內(nèi)容有變動(dòng)。
2 A頁(yè)面點(diǎn)擊按鈕,顯示登錄界面,登錄后,跳轉(zhuǎn)到B頁(yè)面。
在設(shè)計(jì)登錄模塊的時(shí)候需要考慮到這兩種情況的不同處理。
登錄界面和注冊(cè)、修改密碼等界面邏輯聯(lián)系密切,界面相似,也可以采用單個(gè)Activity+多個(gè)Fragment的方式實(shí)現(xiàn)。
商品詳情頁(yè)面通常是即有圖片,又有文字,而且為了美觀,圖片和文字還會(huì)混和排版;可以在服務(wù)器端把圖片和文字合成一個(gè)網(wǎng)頁(yè),APP端使用webview控件顯示。
電商APP常在多個(gè)頁(yè)面有購(gòu)物車小圖標(biāo),上面有角標(biāo)顯示購(gòu)物車?yán)锏纳唐窋?shù)量。
在修改購(gòu)物車?yán)锏纳唐窋?shù)量時(shí),可以采用發(fā)廣播的方式,便于多個(gè)模塊都可以收到消息,更新角標(biāo)數(shù)字。
如果同一個(gè)賬號(hào)只能在一個(gè)設(shè)備上同時(shí)登錄,購(gòu)物車數(shù)據(jù)可以做本地緩存處理;這樣沒(méi)必要每次進(jìn)入購(gòu)物車都從服務(wù)器獲取數(shù)據(jù)。
如果同一個(gè)賬號(hào)可以在多個(gè)設(shè)備上同時(shí)登錄,需要考慮購(gòu)物車?yán)锏臄?shù)據(jù)同步處理;且購(gòu)物車數(shù)據(jù)最好不做緩存處理,每次進(jìn)入購(gòu)物車時(shí)都從服務(wù)器獲取數(shù)據(jù)。
商品展示常用的有兩種方式,一是列表展示,一是宮格展示;在開(kāi)發(fā)時(shí),需考慮到這兩種情況的轉(zhuǎn)換,如產(chǎn)品可能開(kāi)始要求列表展示,后面又要求宮格展示。
可以使用RecylerView實(shí)現(xiàn)商品展示,方便不同表現(xiàn)形式的轉(zhuǎn)換。
36.7個(gè)人中心頁(yè)面功能設(shè)計(jì)
在電商類APP中,常需在個(gè)人中心頁(yè)面顯示各類訂單個(gè)數(shù)等數(shù)據(jù),這也可以采用廣播的方式處理;在用戶下單的時(shí)候發(fā)送廣播給個(gè)人中心,個(gè)人中心收到廣播后,更新相關(guān)數(shù)據(jù)。
個(gè)人中心頁(yè)面展示的數(shù)據(jù)比較雜,在服務(wù)器端可能屬于多個(gè)業(yè)務(wù)模塊,可以像首頁(yè)一樣,設(shè)計(jì)成調(diào)用多個(gè)接口從服務(wù)器返回?cái)?shù)據(jù),只要有一個(gè)接口返回?cái)?shù)據(jù)了,就顯示在頁(yè)面上,避免用戶長(zhǎng)時(shí)間的看到空白頁(yè)面。
在輸入搜索內(nèi)容時(shí),顯示的輸入法鍵盤上可以設(shè)置顯示搜索按鈕,方便用戶輸入完內(nèi)容后,直接點(diǎn)擊輸入法鍵盤上的搜索按鈕進(jìn)行搜索,具體代碼如下:
mSearchEdit.setOnEditorActionListener(newTextView.OnEditorActionListener() {
@Override
public booleanonEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId ==EditorInfo.IME_ACTION_SEARCH){
InputMethodManager imm =
(InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
//隱藏輸入法鍵盤
if(imm.isActive()){
imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), 0 );
}
//在此加入啟動(dòng)搜索功能的代碼
…
return true;
}
return false;
}
});
在XML文件中,做如下配置:
…
android:imeOptions="actionSearch"
…
/>
34.9 WebView功能設(shè)計(jì)
在使用WebView控件時(shí),除了設(shè)置是否支持JS、緩存大小、緩存模式、文字編碼類型、圖片縮放和網(wǎng)頁(yè)縮放等外,還需重寫許多函數(shù),具體如下:
mWebView.setWebViewClient(newWebViewClient() {
@Override
public booleanshouldOverrideUrlLoading(WebView view, String url) {
if(url.startsWith("http:") || url.startsWith("https:") ) {
return false;
}
//網(wǎng)頁(yè)中如果有tel:、mailto:這樣的鏈接,需要單獨(dú)處理??????????????? taskUrl = url;
urlTask();
return true;
}
//在以下幾個(gè)函數(shù)中,需要關(guān)閉加載提示框
@Override
public void onPageFinished(WebViewview, String url) {
super.onPageFinished(view,url);
UIHelper.dismiss(dialogFragment);
}
@Override
public void onReceivedError(WebViewview, int errorCode, String description, String failingUrl) {
super.onReceivedError(view,errorCode, description, failingUrl);
UIHelper.dismiss(dialogFragment);
//顯示提示用戶遇到錯(cuò)誤,需要重新加載的網(wǎng)頁(yè)
mWebView.loadUrl("file:///android_asset/error.html");
}
@Override
public voidonReceivedHttpError(WebView view, WebResourceRequest request,WebResourceResponse errorResponse) {
super.onReceivedHttpError(view,request, errorResponse);
UIHelper.dismiss(dialogFragment);
//顯示提示用戶遇到錯(cuò)誤,需要重新加載的網(wǎng)頁(yè)
mWebView.loadUrl("file:///android_asset/error.html");
}
});
}
//返回鍵處理
public boolean onKeyDown(int keyCode,KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)&&
mWebView.canGoBack()){
mWebView.goBack(); //goBack()表示返回WebView的上一頁(yè)面
return true;
}
return super.onKeyDown(keyCode, event);
}
publicvoid urlTask() {
if(taskUrl.startsWith("tel:")) {
//Android6.0系統(tǒng)需要?jiǎng)討B(tài)申請(qǐng)權(quán)限
if(EasyPermissions.hasPermissions(this,
Manifest.permission.CALL_PHONE)){
// Have permission, do thething!
Intent intent = newIntent(Intent.ACTION_VIEW,
Uri.parse(taskUrl));
startActivity(intent);
} else {
// Ask for one permission
EasyPermissions.requestPermissions(this,
getString(R.string.rationale_call_phone),
RC_TEL_PERM,
Manifest.permission.CALL_PHONE);
}
} else {
Intent intent = newIntent(Intent.ACTION_VIEW,
Uri.parse(taskUrl));
startActivity(intent);
}
}
34.10出錯(cuò)提示功能設(shè)計(jì)
APP在運(yùn)行過(guò)程中遇到出錯(cuò)的情況,通常是顯示Toast或?qū)υ捒?,提示用戶出錯(cuò)了。
但如果從服務(wù)器獲取數(shù)據(jù)時(shí)出錯(cuò)了,需要特別處理:
1 由于網(wǎng)絡(luò)狀況不好導(dǎo)致的出錯(cuò),如手機(jī)信號(hào)不好時(shí)容易出現(xiàn)掉網(wǎng)、斷網(wǎng)和連接超時(shí)等,此時(shí)應(yīng)顯示一個(gè)提示用戶檢查網(wǎng)絡(luò)狀況并重新加載的界面。
2 由于服務(wù)器內(nèi)部出現(xiàn)錯(cuò)誤導(dǎo)致無(wú)法獲取數(shù)據(jù),如服務(wù)器端提供的數(shù)據(jù)類型有變,導(dǎo)致APP無(wú)法正常解析數(shù)據(jù),或用戶的賬戶權(quán)限配置出錯(cuò)了等等,這時(shí)即使用戶重新加載,也無(wú)法獲取到數(shù)據(jù);這就不能讓用戶重新加載,而是提示用戶聯(lián)系客服等解決問(wèn)題。
網(wǎng)絡(luò)層向業(yè)務(wù)層傳遞數(shù)據(jù)時(shí),最好傳遞一個(gè)標(biāo)識(shí)出錯(cuò)原因的狀態(tài)碼,方便業(yè)務(wù)層的處理。
在開(kāi)發(fā)各功能界面的時(shí)候,就需考慮獲取到數(shù)據(jù),獲取的數(shù)據(jù)為空和出錯(cuò)這幾種情況下顯示的不同界面。
當(dāng)向服務(wù)器提交數(shù)據(jù)時(shí)出錯(cuò),無(wú)論哪種原因?qū)е鲁鲥e(cuò),都需停留在當(dāng)前界面,而不能銷毀當(dāng)前界面,顯示一個(gè)新界面。
APP從服務(wù)器端或本地加載數(shù)據(jù)的時(shí)候,都需要一段時(shí)間,在此過(guò)程中,如果布局文件中的控件都設(shè)置為可見(jiàn),那界面上需要顯示數(shù)據(jù)的地方會(huì)顯示為空白,整個(gè)頁(yè)面一塊白,一塊有內(nèi)容,顯得斑斑點(diǎn)點(diǎn);尤其是用到TextView的地方,如在XML文件中做了配置:
android:text="@string/order_text"/>
%1$s張訂單
界面上就會(huì)顯示” %1$s張訂單”的字符串,用戶感官不好。
可以在XML文件的根標(biāo)簽中,所有的控件不可見(jiàn):
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
…
獲取到數(shù)據(jù)后,再把相關(guān)控件設(shè)置為可見(jiàn),這樣就避免了上述情況。