W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
編寫:Lin-H - 原文:http://developer.android.com/training/implementing-navigation/temporal.html
向后導(dǎo)航(Back navigation)是用戶根據(jù)屏幕歷史記錄返回之前所查看的界面。所有Android設(shè)備都可以為這種導(dǎo)航提供后退按鈕,所以你的app不需要在UI中添加后退按鈕。
在幾乎所有情況下,當(dāng)用戶在應(yīng)用中進(jìn)行導(dǎo)航時(shí),系統(tǒng)會(huì)保存activity的后退棧。這樣當(dāng)用戶點(diǎn)擊后退按鈕時(shí),系統(tǒng)可以正確地向后導(dǎo)航。但是,有少數(shù)幾種情況需要手動(dòng)指定app的后退操作,來提供更好的用戶體驗(yàn)。
Back Navigation 設(shè)計(jì)
在繼續(xù)閱讀篇文章之前,你應(yīng)該先在Navigation design guide中對(duì)后退導(dǎo)航的概念和設(shè)計(jì)準(zhǔn)則有個(gè)了解。
手動(dòng)指定后退操作需要的導(dǎo)航模式:
當(dāng)用戶從notification(通知),app widget,navigation drawer直接進(jìn)入深層次activity。
用戶在fragment之間切換的某些情況。
當(dāng)用戶在WebView中對(duì)網(wǎng)頁進(jìn)行導(dǎo)航。
下面說明如何在這幾種情況下實(shí)現(xiàn)恰當(dāng)?shù)南蚝髮?dǎo)航。
一般而言,當(dāng)用戶從一個(gè)activity導(dǎo)航到下一個(gè)時(shí),系統(tǒng)會(huì)遞增地創(chuàng)建后退棧。但是當(dāng)用戶從一個(gè)在自己的任務(wù)中啟動(dòng)activity的深度鏈接進(jìn)入app,你就有必要去同步新的后退棧,因?yàn)樾碌腶ctivity是運(yùn)行在一個(gè)沒有任何后退棧的任務(wù)中。
例如,當(dāng)用戶從通知進(jìn)入你的app中的深層activity時(shí),你應(yīng)該添加別的activity到你的任務(wù)的后退棧中,這樣當(dāng)點(diǎn)擊后退(Back)時(shí)向上導(dǎo)航,而不是退出app。這個(gè)模式在Navigation design guide中有更詳細(xì)的介紹。
從Android 4.1 (API level 16)開始,你可以通過指定<activity>
元素中的android:parentActivityName屬性來聲明每一個(gè)activity的邏輯父activity。這樣系統(tǒng)可以使導(dǎo)航模式變得更容易,因?yàn)橄到y(tǒng)可以根據(jù)這些信息判斷邏輯Back Up navigation的路徑。
如果你的app需要支持Android 4.0以下版本,在你的app中包含Support Library并添加<meta-data>
元素到<activity>
中。然后指定父activity的值為android.support.PARENT_ACTIVITY
,并匹配android:parentActivityName的值。
例如:
<application ... >
...
<!-- main/home activity (沒有父activity) -->
<activity
android:name="com.example.myfirstapp.MainActivity" ...>
...
</activity>
<!-- 主activity的一個(gè)子activity -->
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- 4.1 以下的版本需要使用meta-data元素 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
當(dāng)父activity用這種方式聲明,你就可以使用NavUtils API,通過確定每個(gè)activity相應(yīng)的父activity來同步新的后退棧。
在發(fā)生用戶進(jìn)入app的事件時(shí),開始添加activity到后退棧中。就是說,使用TaskStackBuilder API定義每個(gè)被放到新后退棧的activity,不使用startActivity()。然后調(diào)用startActivities()來啟動(dòng)目標(biāo)activity,或調(diào)用getPendingIntent()來創(chuàng)建相應(yīng)的PendingIntent。
例如,當(dāng)用戶從通知進(jìn)入你的app中的深層activity時(shí),你可以使用這段代碼來創(chuàng)建一個(gè)啟動(dòng)activity并把新后退棧插入目標(biāo)任務(wù)的PendingIntent。
// 當(dāng)用戶選擇通知時(shí),啟動(dòng)activity的intent
Intent detailsIntent = new Intent(this, DetailsActivity.class);
// 使用TaskStackBuilder創(chuàng)建后退棧,并獲取PendingIntent
PendingIntent pendingIntent =
TaskStackBuilder.create(this)
// 添加所有DetailsActivity的父activity到棧中,
// 然后再添加DetailsActivity自己
.addNextIntentWithParentStack(upIntent)
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent);
...
產(chǎn)生的PendingIntent不僅指定了啟動(dòng)哪個(gè)activity(被detailsIntent
所定義)還指定了要插入任務(wù)(所有被detailsIntent
定義的DetailsActivity
)的后退棧。所以當(dāng)DetailsActivity
啟動(dòng)時(shí),點(diǎn)擊Back向后導(dǎo)航至每一個(gè)DetailsActivity
類的父activity。
Note:為了使addNextIntentWithParentStack()方法起作用,像上面所說那樣,你必須在你的manifest文件中使用android:parentActivityName(和相應(yīng)的元素
<meta-data>
)屬性聲明每個(gè)activity的邏輯父activity。
當(dāng)在app中使用fragment時(shí),個(gè)別的FragmentTransaction對(duì)象可以代表要加入后退棧中變化的內(nèi)容。例如,如果你要在手機(jī)上通過交換fragment實(shí)現(xiàn)一個(gè)master/detail flow(主/詳細(xì)流程),你就要保證點(diǎn)擊Back按鈕可以從detail screen返回到master screen。要這么做,你可以在提交事務(wù)(transaction)之前調(diào)用addToBackStack():
// 使用framework FragmentManager
// 或support package FragmentManager (getSupportFragmentManager).
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail")
// 提交這一事務(wù)到后退棧中
.addToBackStack()
.commit();
當(dāng)后退棧中有FragmentTransaction對(duì)象并且用戶點(diǎn)擊Back按鈕時(shí),FragmentManager會(huì)從后退棧中彈出最近的事務(wù),然后執(zhí)行反向操作(例如如果事務(wù)添加了一個(gè)fragment,那么就刪除一個(gè)fragment)。
Note:當(dāng)事務(wù)用作水平導(dǎo)航(例如切換tab)或者修改內(nèi)容外觀(例如在調(diào)整filter時(shí))時(shí),不要將這個(gè)事務(wù)添加到后退棧中。更多關(guān)于向后導(dǎo)航的恰當(dāng)時(shí)間的信息,詳見Navigation design guide。
如果你的應(yīng)用更新了別的UI元素來反應(yīng)當(dāng)前的fragment狀態(tài),例如action bar,記得當(dāng)你提交事務(wù)時(shí)更新UI。除了在提交事務(wù)的時(shí)候,在后退棧發(fā)生變化時(shí)也要更新你的UI。你可以設(shè)置一個(gè)FragmentManager.OnBackStackChangedListener來監(jiān)聽FragmentTransaction什么時(shí)候復(fù)原:
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
// 在這里更新你的UI
}
});
如果你的應(yīng)用的一部分包含在WebView中,可以通過瀏覽器歷史使用Back。要這么做,如果WebView有歷史記錄,你可以重寫onBackPressed()并代理給WebView:
@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
return;
}
// 否則遵從系統(tǒng)的默認(rèn)操作.
super.onBackPressed();
}
要注意當(dāng)使用這一機(jī)制時(shí),高動(dòng)態(tài)化的頁面會(huì)產(chǎn)生大量歷史。會(huì)生成大量歷史的頁面,例如經(jīng)常改變文件散列(document hash)的頁面,當(dāng)要退出你的activity時(shí),這會(huì)使你的用戶感到繁瑣。
更多關(guān)于使用WebView的信息,詳見Building Web Apps in WebView。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: