W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
編寫:Lin-H - 原文:http://developer.android.com/training/implementing-navigation/ancestral.html
所有不是從主屏幕("home"屏幕)進(jìn)入app的,都應(yīng)該給用戶提供一種方法,通過點擊action bar中的Up按鈕??梢曰氐絘pp的結(jié)構(gòu)層次中邏輯父屏幕。本課程向你說明如何正確地實現(xiàn)這一操作。
Up Navigation 設(shè)計
Designing Effective Navigation和the Navigation design guide中描述了向上導(dǎo)航的概念和設(shè)計準(zhǔn)則。
Figure 1. action bar中的Up按鈕.
要實現(xiàn)向上導(dǎo)航,第一步就是為每一個activity聲明合適的父activity。這么做可以使系統(tǒng)簡化導(dǎo)航模式,例如向上導(dǎo)航,因為系統(tǒng)可以從manifest文件中判斷它的邏輯父(logical parent)activity。
從Android 4.1 (API level 16)開始,你可以通過指定<activity>
元素中的android:parentActivityName屬性來聲明每一個activity的邏輯父activity。
如果你的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的一個子activity -->
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- 父activity的meta-data,用來支持4.0以下版本 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
在父activity這樣聲明后,你可以使用NavUtils API進(jìn)行向上導(dǎo)航操作,就像下一面這節(jié)。
要使用action bar的app圖標(biāo)來完成向上導(dǎo)航,需要調(diào)用setDisplayHomeAsUpEnabled():
@Override
public void onCreate(Bundle savedInstanceState) {
...
getActionBar().setDisplayHomeAsUpEnabled(true);
}
這樣,在app旁添加了一個左向符號,并用作操作按鈕。當(dāng)用戶點擊它時,你的activity會接收一個對onOptionsItemSelected()的調(diào)用。操作的ID是android.R.id.home
。
要在用戶點擊app圖標(biāo)時向上導(dǎo)航,你可以使用NavUtils類中的靜態(tài)方法navigateUpFromSameTask()。當(dāng)你調(diào)用這一方法時,系統(tǒng)會結(jié)束當(dāng)前的activity并啟動(或恢復(fù))相應(yīng)的父activity。如果目標(biāo)activity在任務(wù)的后退棧中(back stack),則目標(biāo)activity會像FLAG_ACTIVITY_CLEAR_TOP定義的那樣,提到棧頂。提到棧頂?shù)姆绞饺Q于父activity是否處理了對onNewIntent()的調(diào)用。
例如:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// 對action bar的Up/Home按鈕做出反應(yīng)
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
但是,只能是當(dāng)你的app擁有當(dāng)前任務(wù)(current task)(用戶從你的app中發(fā)起這一任務(wù))時navigateUpFromSameTask()才有用。如果你的activity是從別的app的任務(wù)中啟動的話,向上導(dǎo)航操作就應(yīng)該創(chuàng)建一個屬于你的app的新任務(wù),并需要你創(chuàng)建一個新的后退棧。
如果你的activity提供了任何允許被別的app啟動的intent filters,那么你應(yīng)該實現(xiàn)onOptionsItemSelected()回調(diào),在用戶從別的app任務(wù)進(jìn)入你的activity后,點擊Up按鈕,在向上導(dǎo)航之前你的app用相應(yīng)的后退棧開啟一個新的任務(wù)。
在這么做之前,你可以先調(diào)用shouldUpRecreateTask()來檢查當(dāng)前的activity實例是否在另一個不同的app任務(wù)中。如果返回true,就使用TaskStackBuilder創(chuàng)建一個新任務(wù)?;蛘?,你可以向上面那樣使用navigateUpFromSameTask()方法。
例如:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// 對action bar的Up/Home按鈕做出反應(yīng)
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// 這個activity不是這個app任務(wù)的一部分, 所以當(dāng)向上導(dǎo)航時創(chuàng)建
// 用合成后退棧(synthesized back stack)創(chuàng)建一個新任務(wù)。
TaskStackBuilder.create(this)
// 添加這個activity的所有父activity到后退棧中
.addNextIntentWithParentStack(upIntent)
// 向上導(dǎo)航到最近的一個父activity
.startActivities();
} else {
// 這個activity是這個app任務(wù)的一部分, 所以
// 向上導(dǎo)航至邏輯父activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
Note:為了能使addNextIntentWithParentStack()方法起作用,你必須像上面說的那樣,在你的manifest文件中使用android:parentActivityName(和相應(yīng)的
<meta-data>
元素)屬性聲明所有的activity的邏輯父activity。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: