| page.title=Providing Up Navigation |
| page.tags=up navigation,NavUtils,TaskStackBuilder |
| |
| trainingnavtop=true |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| |
| <h2>This lesson teaches you to:</h2> |
| <ol> |
| <li><a href="#SpecifyParent">Specify the Parent Activity</a></li> |
| <li><a href="#up">Add Up Action</a></li> |
| <li><a href="#NavigateUp">Navigate Up to Parent Activity</a></li> |
| </ol> |
| |
| <h2>You should also read</h2> |
| <ul> |
| <li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li> |
| <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li> |
| <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li> |
| </ul> |
| |
| <h2>Try it out</h2> |
| |
| <div class="download-box"> |
| <a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip" |
| class="button">Download the sample app</a> |
| <p class="filename">EffectiveNavigation.zip</p> |
| </div> |
| |
| </div> |
| </div> |
| |
| |
| <p>All screens in your app that are not the main entrance to your app (the "home" screen) |
| should offer the user a way to navigate to the logical parent screen in the app's hierarchy by |
| pressing the <em>Up</em> button in the <a |
| href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>. |
| This lesson shows you how to properly implement this behavior.</p> |
| |
| <div class="note design"> |
| <p><strong>Up Navigation Design</strong></p> |
| <p>The concepts and principles for <em>Up</em> navigation are described in <a |
| href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective |
| Navigation</a> and the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design |
| guide.</p> |
| </div> |
| |
| |
| <img src="{@docRoot}images/training/implementing-navigation-up.png" id="figure-up"> |
| <p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p> |
| |
| |
| |
| <h2 id="SpecifyParent">Specify the Parent Activity</h2> |
| |
| <p>To implement <em>Up</em> navigation, the first step is to declare which activity is the |
| appropriate parent for each activity. Doing so allows the system to facilitate navigation patterns |
| such as <em>Up</em> because the system can determine the logical parent activity from |
| the manifest file.</p> |
| |
| <p>Beginning in Android 4.1 (API level 16), you can declare the logical parent of each |
| activity by specifying the <a |
| href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code |
| android:parentActivityName}</a> attribute |
| in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> |
| element.</p> |
| |
| <p>If your app supports Android 4.0 and lower, include the |
| <a href="{@docRoot}tools/support-library/index.html">Support Library</a> with your app and |
| add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> |
| element inside the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <activity>}</a>. Then specify the parent activity as the value |
| for {@code android.support.PARENT_ACTIVITY}, matching the <a |
| href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code |
| android:parentActivityName}</a> attribute.</p> |
| |
| <p>For example:</p> |
| |
| <pre> |
| <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> |
| </pre> |
| |
| <p>With the parent activity declared this way, you can navigate <em>Up</em> |
| to the appropriate parent using the {@link android.support.v4.app.NavUtils} APIs, as shown in |
| the following sections.</p> |
| |
| |
| <h2 id="up">Add Up Action</h2> |
| |
| <p>To allow <em>Up</em> navigation with the app icon in the action bar, call |
| {@link android.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}:</p> |
| |
| <pre> |
| {@literal @}Override |
| public void onCreate(Bundle savedInstanceState) { |
| ... |
| getActionBar().setDisplayHomeAsUpEnabled(true); |
| } |
| </pre> |
| |
| <p>This adds a left-facing caret alongside the app icon and enables it as an action button |
| such that when the user presses it, your activity receives a call to |
| {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. The |
| ID for the action is {@code android.R.id.home}.</p> |
| |
| |
| |
| <h2 id="NavigateUp">Navigate Up to Parent Activity</h2> |
| |
| <p>To navigate up when the user presses the app icon, you can use the {@link |
| android.support.v4.app.NavUtils} class's static method, |
| {@link android.support.v4.app.NavUtils#navigateUpFromSameTask |
| navigateUpFromSameTask()}. When you call this method, it finishes the current activity and |
| starts (or resumes) the appropriate parent activity. |
| If the target parent activity is in the task's back stack, it is brought |
| forward as defined by {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.</p> |
| |
| <p>For example:</p> |
| |
| <pre> |
| {@literal @}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); |
| } |
| </pre> |
| |
| <p>However, using {@link android.support.v4.app.NavUtils#navigateUpFromSameTask |
| navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current |
| task</strong> (that is, the user began this task from your app). If that's not true and your |
| activity was started in a task that belongs to a different app, then |
| navigating <em>Up</em> should create a new task that belongs to your app, which |
| requires that you create a new back stack.</p> |
| |
| |
| <h3 id="BuildBackStack">Navigate up with a new back stack</h3> |
| |
| <p>If your activity provides any <a |
| href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a> |
| that allow other apps to start the |
| activity, you should implement the {@link android.app.Activity#onOptionsItemSelected |
| onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button |
| after entering your activity from another app's task, your app starts a new task |
| with the appropriate back stack before navigating up.</p> |
| |
| <p>You can do so by first calling |
| {@link android.support.v4.app.NavUtils#shouldUpRecreateTask shouldUpRecreateTask()} to check |
| whether the current activity instance exists in a different app's task. If |
| it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}. |
| Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask |
| navigateUpFromSameTask()} method as shown above.</p> |
| |
| <p>For example:</p> |
| |
| <pre> |
| {@literal @}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); |
| } |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> In order for the {@link |
| android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()} |
| method to work, |
| you must declare the logical parent of each activity in your manifest file, using the |
| <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code |
| android:parentActivityName}</a> attribute (and corresponding <a |
| href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element) |
| as described above.</p> |