Home | History | Annotate | Download | only in implementing-navigation
      1 page.title=Providing Up Navigation
      2 page.tags=up navigation,NavUtils,TaskStackBuilder
      3 
      4 trainingnavtop=true
      5 
      6 @jd:body
      7 
      8 <div id="tb-wrapper">
      9 <div id="tb">
     10 
     11 <h2>This lesson teaches you to:</h2>
     12 <ol>
     13   <li><a href="#SpecifyParent">Specify the Parent Activity</a></li>
     14   <li><a href="#up">Add Up Action</a></li>
     15   <li><a href="#NavigateUp">Navigate Up to Parent Activity</a></li>
     16 </ol>
     17 
     18 <h2>You should also read</h2>
     19 <ul>
     20   <li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
     21   <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
     22   <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
     23 </ul>
     24 
     25 <h2>Try it out</h2>
     26 
     27 <div class="download-box">
     28 <a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
     29   class="button">Download the sample app</a>
     30 <p class="filename">EffectiveNavigation.zip</p>
     31 </div>
     32 
     33 </div>
     34 </div>
     35 
     36 
     37 <p>All screens in your app that are not the main entrance to your app (the "home" screen)
     38 should offer the user a way to navigate to the logical parent screen in the app's hierarchy by
     39 pressing the <em>Up</em> button in the <a
     40 href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>.
     41 This lesson shows you how to properly implement this behavior.</p>
     42 
     43 <div class="note design">
     44 <p><strong>Up Navigation Design</strong></p>
     45 <p>The concepts and principles for <em>Up</em> navigation are described in <a
     46 href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective
     47 Navigation</a> and the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design
     48 guide.</p>
     49 </div>
     50 
     51 
     52 <img src="{@docRoot}images/training/implementing-navigation-up.png" id="figure-up">
     53 <p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p>
     54 
     55 
     56 
     57 <h2 id="SpecifyParent">Specify the Parent Activity</h2>
     58 
     59 <p>To implement <em>Up</em> navigation, the first step is to declare which activity is the
     60 appropriate parent for each activity. Doing so allows the system to facilitate navigation patterns
     61 such as <em>Up</em> because the system can determine the logical parent activity from
     62 the manifest file.</p>
     63 
     64 <p>Beginning in Android 4.1 (API level 16), you can declare the logical parent of each
     65 activity by specifying the <a
     66 href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
     67 android:parentActivityName}</a> attribute
     68 in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity>}</a>
     69 element.</p>
     70 
     71 <p>If your app supports Android 4.0 and lower, include the
     72 <a href="{@docRoot}tools/support-library/index.html">Support Library</a> with your app and
     73 add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a>
     74 element inside the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
     75 &lt;activity>}</a>. Then specify the parent activity as the value
     76 for {@code android.support.PARENT_ACTIVITY}, matching the <a
     77 href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
     78 android:parentActivityName}</a> attribute.</p>
     79 
     80 <p>For example:</p>
     81 
     82 <pre>
     83 &lt;application ... >
     84     ...
     85     &lt;!-- The main/home activity (it has no parent activity) -->
     86     &lt;activity
     87         android:name="com.example.myfirstapp.MainActivity" ...>
     88         ...
     89     &lt;/activity>
     90     &lt;!-- A child of the main activity -->
     91     &lt;activity
     92         android:name="com.example.myfirstapp.DisplayMessageActivity"
     93         android:label="&#64;string/title_activity_display_message"
     94         android:parentActivityName="com.example.myfirstapp.MainActivity" >
     95         &lt;!-- Parent activity meta-data to support 4.0 and lower -->
     96         &lt;meta-data
     97             android:name="android.support.PARENT_ACTIVITY"
     98             android:value="com.example.myfirstapp.MainActivity" />
     99     &lt;/activity>
    100 &lt;/application>
    101 </pre>
    102 
    103 <p>With the parent activity declared this way, you can navigate <em>Up</em>
    104 to the appropriate parent using the {@link android.support.v4.app.NavUtils} APIs, as shown in
    105 the following sections.</p>
    106 
    107 
    108 <h2 id="up">Add Up Action</h2>
    109 
    110 <p>To allow <em>Up</em> navigation with the app icon in the action bar, call
    111 {@link android.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}:</p>
    112 
    113 <pre>
    114 {@literal @}Override
    115 public void onCreate(Bundle savedInstanceState) {
    116     ...
    117     getActionBar().setDisplayHomeAsUpEnabled(true);
    118 }
    119 </pre>
    120 
    121 <p>This adds a left-facing caret alongside the app icon and enables it as an action button
    122 such that when the user presses it, your activity receives a call to
    123 {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. The
    124 ID for the action is {@code android.R.id.home}.</p>
    125 
    126 
    127 
    128 <h2 id="NavigateUp">Navigate Up to Parent Activity</h2>
    129 
    130 <p>To navigate up when the user presses the app icon, you can use the {@link
    131 android.support.v4.app.NavUtils} class's static method,
    132 {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
    133 navigateUpFromSameTask()}. When you call this method, it finishes the current activity and
    134 starts (or resumes) the appropriate parent activity.
    135 If the target parent activity is in the task's back stack, it is brought
    136 forward. The way it is brought forward depends on whether the parent activity
    137 is able to handle an {@link
    138 android.app.Activity#onNewIntent onNewIntent()} call:</p>
    139 
    140 <ul>
    141     <li>If the parent activity has launch mode <a
    142     href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
    143     &lt;singleTop>}</a>, or the <code>up</code> intent contains {@link
    144     android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}, the parent activity is
    145     brought to the top of the stack, and receives the intent through its
    146     {@link android.app.Activity#onNewIntent onNewIntent()} method.</li>
    147 
    148     <li>If the parent activity has launch mode <a
    149     href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
    150     &lt;standard>}</a>, and the <code>up</code> intent does not contain
    151     {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}, the parent activity
    152     is popped off the stack, and a new instance of that activity is created on
    153     top of the stack to receive the intent.</li>
    154 </ul>
    155 
    156 <p>For example:</p>
    157 
    158 <pre>
    159 {@literal @}Override
    160 public boolean onOptionsItemSelected(MenuItem item) {
    161     switch (item.getItemId()) {
    162     // Respond to the action bar's Up/Home button
    163     case android.R.id.home:
    164         NavUtils.navigateUpFromSameTask(this);
    165         return true;
    166     }
    167     return super.onOptionsItemSelected(item);
    168 }
    169 </pre>
    170 
    171 <p>However, using {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
    172 navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current
    173 task</strong> (that is, the user began this task from your app). If that's not true and your
    174 activity was started in a task that belongs to a different app, then
    175 navigating <em>Up</em> should create a new task that belongs to your app, which
    176 requires that you create a new back stack.</p>
    177 
    178 <h3 id="BuildBackStack">Navigate up with a new back stack</h3>
    179 
    180 <p>If your activity provides any <a
    181 href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a>
    182 that allow other apps to start the
    183 activity, you should implement the {@link android.app.Activity#onOptionsItemSelected
    184 onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button
    185 after entering your activity from another app's task, your app starts a new task
    186 with the appropriate back stack before navigating up.</p>
    187 
    188 <p>You can do so by first calling
    189 {@link android.support.v4.app.NavUtils#shouldUpRecreateTask shouldUpRecreateTask()} to check
    190 whether the current activity instance exists in a different app's task. If
    191 it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}.
    192 Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
    193 navigateUpFromSameTask()} method as shown above.</p>
    194 
    195 <p>For example:</p>
    196 
    197 <pre>
    198 {@literal @}Override
    199 public boolean onOptionsItemSelected(MenuItem item) {
    200     switch (item.getItemId()) {
    201     // Respond to the action bar's Up/Home button
    202     case android.R.id.home:
    203         Intent upIntent = NavUtils.getParentActivityIntent(this);
    204         if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    205             // This activity is NOT part of this app's task, so create a new task
    206             // when navigating up, with a synthesized back stack.
    207             TaskStackBuilder.create(this)
    208                     // Add all of this activity's parents to the back stack
    209                     .addNextIntentWithParentStack(upIntent)
    210                     // Navigate up to the closest parent
    211                     .startActivities();
    212         } else {
    213             // This activity is part of this app's task, so simply
    214             // navigate up to the logical parent activity.
    215             NavUtils.navigateUpTo(this, upIntent);
    216         }
    217         return true;
    218     }
    219     return super.onOptionsItemSelected(item);
    220 }
    221 </pre>
    222 
    223 <p class="note"><strong>Note:</strong> In order for the {@link
    224 android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()}
    225 method to work,
    226 you must declare the logical parent of each activity in your manifest file, using the
    227 <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
    228 android:parentActivityName}</a> attribute (and corresponding <a
    229 href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a> element)
    230 as described above.</p>
    231