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 as defined by {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.</p>
    137 
    138 <p>For example:</p>
    139 
    140 <pre>
    141 {@literal @}Override
    142 public boolean onOptionsItemSelected(MenuItem item) {
    143     switch (item.getItemId()) {
    144     // Respond to the action bar's Up/Home button
    145     case android.R.id.home:
    146         NavUtils.navigateUpFromSameTask(this);
    147         return true;
    148     }
    149     return super.onOptionsItemSelected(item);
    150 }
    151 </pre>
    152 
    153 <p>However, using {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
    154 navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current
    155 task</strong> (that is, the user began this task from your app). If that's not true and your
    156 activity was started in a task that belongs to a different app, then
    157 navigating <em>Up</em> should create a new task that belongs to your app, which
    158 requires that you create a new back stack.</p>
    159 
    160 
    161 <h3 id="BuildBackStack">Navigate up with a new back stack</h3>
    162 
    163 <p>If your activity provides any <a
    164 href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a>
    165 that allow other apps to start the
    166 activity, you should implement the {@link android.app.Activity#onOptionsItemSelected
    167 onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button
    168 after entering your activity from another app's task, your app starts a new task
    169 with the appropriate back stack before navigating up.</p>
    170 
    171 <p>You can do so by first calling
    172 {@link android.support.v4.app.NavUtils#shouldUpRecreateTask shouldUpRecreateTask()} to check
    173 whether the current activity instance exists in a different app's task. If
    174 it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}.
    175 Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
    176 navigateUpFromSameTask()} method as shown above.</p>
    177 
    178 <p>For example:</p>
    179 
    180 <pre>
    181 {@literal @}Override
    182 public boolean onOptionsItemSelected(MenuItem item) {
    183     switch (item.getItemId()) {
    184     // Respond to the action bar's Up/Home button
    185     case android.R.id.home:
    186         Intent upIntent = NavUtils.getParentActivityIntent(this);
    187         if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    188             // This activity is NOT part of this app's task, so create a new task
    189             // when navigating up, with a synthesized back stack.
    190             TaskStackBuilder.create(this)
    191                     // Add all of this activity's parents to the back stack
    192                     .addNextIntentWithParentStack(upIntent)
    193                     // Navigate up to the closest parent
    194                     .startActivities();
    195         } else {
    196             // This activity is part of this app's task, so simply
    197             // navigate up to the logical parent activity.
    198             NavUtils.navigateUpTo(this, upIntent);
    199         }
    200         return true;
    201     }
    202     return super.onOptionsItemSelected(item);
    203 }
    204 </pre>
    205 
    206 <p class="note"><strong>Note:</strong> In order for the {@link
    207 android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()}
    208 method to work,
    209 you must declare the logical parent of each activity in your manifest file, using the
    210 <a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
    211 android:parentActivityName}</a> attribute (and corresponding <a
    212 href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a> element)
    213 as described above.</p>
    214