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ū)υ捒颍崾居脩舫鲥e(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)茎匠,這樣就避免了上述情況。