1page.title=Providing Up Navigation 2page.tags="up navigation","NavUtils","TaskStackBuilder" 3 4trainingnavtop=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) 38should offer the user a way to navigate to the logical parent screen in the app's hierarchy by 39pressing the <em>Up</em> button in the <a 40href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>. 41This 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 46href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective 47Navigation</a> and the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design 48guide.</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 60appropriate parent for each activity. Doing so allows the system to facilitate navigation patterns 61such as <em>Up</em> because the system can determine the logical parent activity from 62the manifest file.</p> 63 64<p>Beginning in Android 4.1 (API level 16), you can declare the logical parent of each 65activity by specifying the <a 66href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code 67android:parentActivityName}</a> attribute 68in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 69element.</p> 70 71<p>If your app supports Android 4.0 and lower, include the 72<a href="{@docRoot}tools/extras/support-library.html">Support Library</a> with your app and 73add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 74element inside the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 75<activity>}</a>. Then specify the parent activity as the value 76for {@code android.support.PARENT_ACTIVITY}, matching the <a 77href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code 78android:parentActivityName}</a> attribute.</p> 79 80<p>For example:</p> 81 82<pre> 83<application ... > 84 ... 85 <!-- The main/home activity (it has no parent activity) --> 86 <activity 87 android:name="com.example.myfirstapp.MainActivity" ...> 88 ... 89 </activity> 90 <!-- A child of the main activity --> 91 <activity 92 android:name="com.example.myfirstapp.DisplayMessageActivity" 93 android:label="@string/title_activity_display_message" 94 android:parentActivityName="com.example.myfirstapp.MainActivity" > 95 <!-- Parent activity meta-data to support 4.0 and lower --> 96 <meta-data 97 android:name="android.support.PARENT_ACTIVITY" 98 android:value="com.example.myfirstapp.MainActivity" /> 99 </activity> 100</application> 101</pre> 102 103<p>With the parent activity declared this way, you can navigate <em>Up</em> 104to the appropriate parent using the {@link android.support.v4.app.NavUtils} APIs, as shown in 105the 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 115public 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 122such that when the user presses it, your activity receives a call to 123{@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. The 124ID 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 131android.support.v4.app.NavUtils} class's static method, 132{@link android.support.v4.app.NavUtils#navigateUpFromSameTask 133navigateUpFromSameTask()}. When you call this method, it finishes the current activity and 134starts (or resumes) the appropriate parent activity. 135If the target parent activity is in the task's back stack, it is brought 136forward as defined by {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.</p> 137 138<p>For example:</p> 139 140<pre> 141{@literal @}Override 142public 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 154navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current 155task</strong> (that is, the user began this task from your app). If that's not true and your 156activity was started in a task that belongs to a different app, then 157navigating <em>Up</em> should create a new task that belongs to your app, which 158requires 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 164href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a> 165that allow other apps to start the 166activity, you should implement the {@link android.app.Activity#onOptionsItemSelected 167onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button 168after entering your activity from another app's task, your app starts a new task 169with 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 173whether the current activity instance exists in a different app's task. If 174it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}. 175Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask 176navigateUpFromSameTask()} method as shown above.</p> 177 178<p>For example:</p> 179 180<pre> 181{@literal @}Override 182public 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 207android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()} 208method to work, 209you 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 211android:parentActivityName}</a> attribute (and corresponding <a 212href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element) 213as described above.</p> 214