Android 提供向上的導(dǎo)航

2018-08-02 18:08 更新

編寫:Lin-H - 原文:http://developer.android.com/training/implementing-navigation/ancestral.html

所有不是從主屏幕("home"屏幕)進(jìn)入app的,都應(yīng)該給用戶提供一種方法,通過點(diǎn)擊action bar中的Up按鈕??梢曰氐絘pp的結(jié)構(gòu)層次中邏輯父屏幕。本課程向你說明如何正確地實(shí)現(xiàn)這一操作。

Up Navigation 設(shè)計(jì)

Designing Effective Navigation和the Navigation design guide中描述了向上導(dǎo)航的概念和設(shè)計(jì)準(zhǔn)則。

Figure 1. action bar中的Up按鈕.

Figure 1. action bar中的Up按鈕.

指定父Activity

要實(shí)現(xiàn)向上導(dǎo)航,第一步就是為每一個(gè)activity聲明合適的父activity。這么做可以使系統(tǒng)簡化導(dǎo)航模式,例如向上導(dǎo)航,因?yàn)橄到y(tǒng)可以從manifest文件中判斷它的邏輯父(logical parent)activity。

從Android 4.1 (API level 16)開始,你可以通過指定<activity>元素中的android:parentActivityName屬性來聲明每一個(gè)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的一個(gè)子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é)。

添加向上操作(Up Action)

要使用action bar的app圖標(biāo)來完成向上導(dǎo)航,需要調(diào)用setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

這樣,在app旁添加了一個(gè)左向符號(hào),并用作操作按鈕。當(dāng)用戶點(diǎn)擊它時(shí),你的activity會(huì)接收一個(gè)對(duì)onOptionsItemSelected()的調(diào)用。操作的ID是android.R.id.home

向上導(dǎo)航至父activity

要在用戶點(diǎn)擊app圖標(biāo)時(shí)向上導(dǎo)航,你可以使用NavUtils類中的靜態(tài)方法navigateUpFromSameTask()。當(dāng)你調(diào)用這一方法時(shí),系統(tǒng)會(huì)結(jié)束當(dāng)前的activity并啟動(dòng)(或恢復(fù))相應(yīng)的父activity。如果目標(biāo)activity在任務(wù)的后退棧中(back stack),則目標(biāo)activity會(huì)像FLAG_ACTIVITY_CLEAR_TOP定義的那樣,提到棧頂。提到棧頂?shù)姆绞饺Q于父activity是否處理了對(duì)onNewIntent()的調(diào)用。

例如:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // 對(duì)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ù))時(shí)navigateUpFromSameTask()才有用。如果你的activity是從別的app的任務(wù)中啟動(dòng)的話,向上導(dǎo)航操作就應(yīng)該創(chuàng)建一個(gè)屬于你的app的新任務(wù),并需要你創(chuàng)建一個(gè)新的后退棧。

用新的后退棧來向上導(dǎo)航

如果你的activity提供了任何允許被別的app啟動(dòng)的intent filters,那么你應(yīng)該實(shí)現(xiàn)onOptionsItemSelected()回調(diào),在用戶從別的app任務(wù)進(jìn)入你的activity后,點(diǎn)擊Up按鈕,在向上導(dǎo)航之前你的app用相應(yīng)的后退棧開啟一個(gè)新的任務(wù)。

在這么做之前,你可以先調(diào)用shouldUpRecreateTask()來檢查當(dāng)前的activity實(shí)例是否在另一個(gè)不同的app任務(wù)中。如果返回true,就使用TaskStackBuilder創(chuàng)建一個(gè)新任務(wù)?;蛘?,你可以向上面那樣使用navigateUpFromSameTask()方法。

例如:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // 對(duì)action bar的Up/Home按鈕做出反應(yīng)
    case android.R.id.home:
        Intent upIntent = NavUtils.getParentActivityIntent(this);
        if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
            // 這個(gè)activity不是這個(gè)app任務(wù)的一部分, 所以當(dāng)向上導(dǎo)航時(shí)創(chuàng)建
            // 用合成后退棧(synthesized back stack)創(chuàng)建一個(gè)新任務(wù)。
            TaskStackBuilder.create(this)
                    // 添加這個(gè)activity的所有父activity到后退棧中
                    .addNextIntentWithParentStack(upIntent)
                    // 向上導(dǎo)航到最近的一個(gè)父activity
                    .startActivities();
        } else {
            // 這個(gè)activity是這個(gè)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。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)