在你的应用程序中,所有的窗口都不是你的应用程序的主入口(主窗口),应为用户提供了一种按操作栏上up键导航到应用程序层次结构中的逻辑父窗口。本课程将告诉您如何正确实现。
向上导航设计
对于向上导航的概念和原则,在 Designing Effective Navigation 和 Navigation 中描述。
图1. 操作栏上的up按钮
指定父活动the Parent Activity
为了实现向上导航,第一步是确定哪一个是适当的父活动(activity),这样做可以使系统方便使用导航模式,因为系统可以通过manifest文件来确定逻辑父活动。
从android4.1开始,你可以声明每个活动(acticity)的逻辑父活动通过设置<activity>的parentActivityName属性。
如果您的应用程序支持的是Android 4.0或更低的,那么让您的应用程序包含支持库,并添加在<activity>内添加<meta-data>元素。然后指定父活动作为android.support.PARENT_ACTIVITY值,匹配了android:arentActivityName属性。
例如:
<application ... > ... <!-- The main/home activity (it has no parent activity) --> <activity android:name="com.example.myfirstapp.MainActivity" ...> ... </activity> <!-- A child of the main activity --> <activity android:name="com.example.myfirstapp.DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <!-- Parent activity meta-data to support 4.0 and lower --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity> </application>用这种方式声明了父活动,你可以使用NavUtils APIs来导航到适当的父窗口,如下面演示的:
加入Up动作
需要触发操作栏上的Up导航图标,使用setDisplayHomeAsUpEnabled()函数
@Override public void onCreate(Bundle savedInstanceState) { ... getActionBar().setDisplayHomeAsUpEnabled(true); }导航到父活动(activity)
当用户按下app图标触发up动作,您可以使用NavUtils类的静态方法, navigateUpFromSameTask ()。当你调用这个方法,它完成当前的活动并启动(或恢复)相应的父活动。如果目标父活动是在该任务back stack,它可以通过FLAG_ACTIVITY_CLEAR_TOP定义。
例如:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); }但是,只有当你的应用程序是当前任务的所有者(即用户从您的应用程序开始这个任务),使用navigateUpFromSameTask ()是合适的 。如果不是这样,你的活动始于属于一个不同的应用程序中的任务,这要求您创建一个新的back stack。
在一个新的back stack中导航
如果你的活动(activity)提供任何意图过滤器(intent filters )允许其他应用程序来启动活动(activity),你应该实现onOptionsItemSelected ()回调。例如,如果用户从其他应用程序的任务,进入您的活动(activity)后,按下up键,在导航之前,你的应用程序开始一个新的任务在一个合适back stack。
您可以先调用shouldUpRecreateTask ()来检查当前活动实例是否存活在不同的应用程序的任务中,如果返回true ,然后用TaskStackBuilder建立一个新的任务。否则,你可以使用navigateUpFromSameTask ()方法,如之前所示。
例如:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Respond to the action bar's Up/Home button case android.R.id.home: Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { // This activity is NOT part of this app's task, so create a new task // when navigating up, with a synthesized back stack. TaskStackBuilder.create(this) // Add all of this activity's parents to the back stack .addNextIntentWithParentStack(upIntent) // Navigate up to the closest parent .startActivities(); } else { // This activity is part of this app's task, so simply // navigate up to the logical parent activity. NavUtils.navigateUpTo(this, upIntent); } return true; } return super.onOptionsItemSelected(item); }注:为了使addNextIntentWithParentStack ()方法工作,你必须声明每项活动的逻辑父窗口在你的manifest文件中,使用android :parentActivityName属性(以及相应的<meta-data>元素)如上所述。