blob: 8aa0fd62ebdd203bdb046a344a897855c718f670 [file] [log] [blame]
Scott Main7c840552013-03-26 18:53:01 -07001page.title=Providing Up Navigation
Joe Fernandez33baa5a2013-11-14 11:41:19 -08002page.tags=up navigation,NavUtils,TaskStackBuilder
Roman Nurik19266f72012-03-12 21:48:47 -07003
4trainingnavtop=true
Roman Nurik19266f72012-03-12 21:48:47 -07005
6@jd:body
7
8<div id="tb-wrapper">
9<div id="tb">
10
11<h2>This lesson teaches you to:</h2>
12<ol>
Scott Main7c840552013-03-26 18:53:01 -070013 <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>
Roman Nurik19266f72012-03-12 21:48:47 -070016</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>
Scott Main50e990c2012-06-21 17:14:39 -070021 <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
Roman Nurik19266f72012-03-12 21:48:47 -070022 <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
Scott Main7c840552013-03-26 18:53:01 -070037<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>
Roman Nurik19266f72012-03-12 21:48:47 -070050
51
Scott Main7c840552013-03-26 18:53:01 -070052<img src="{@docRoot}images/training/implementing-navigation-up.png" id="figure-up">
Roman Nurik19266f72012-03-12 21:48:47 -070053<p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p>
54
Roman Nurik19266f72012-03-12 21:48:47 -070055
Scott Main7c840552013-03-26 18:53:01 -070056
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 &lt;activity>}</a>
69element.</p>
70
71<p>If your app supports Android 4.0 and lower, include the
Scott Main4e2c9dc2013-07-23 19:35:17 -070072<a href="{@docRoot}tools/support-library/index.html">Support Library</a> with your app and
Scott Main7c840552013-03-26 18:53:01 -070073add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a>
74element inside the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
75&lt;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&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>
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>
Roman Nurik19266f72012-03-12 21:48:47 -0700112
113<pre>
114{@literal @}Override
115public void onCreate(Bundle savedInstanceState) {
116 ...
117 getActionBar().setDisplayHomeAsUpEnabled(true);
Roman Nurik19266f72012-03-12 21:48:47 -0700118}
119</pre>
120
Scott Main7c840552013-03-26 18:53:01 -0700121<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
Andrew Solovay4d06d972014-07-10 13:23:45 -0700136forward. The way it is brought forward depends on whether the parent activity
137is able to handle an {@link
138android.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>
Scott Main7c840552013-03-26 18:53:01 -0700155
156<p>For example:</p>
Roman Nurik19266f72012-03-12 21:48:47 -0700157
158<pre>
159{@literal @}Override
160public boolean onOptionsItemSelected(MenuItem item) {
161 switch (item.getItemId()) {
Scott Main7c840552013-03-26 18:53:01 -0700162 // Respond to the action bar's Up/Home button
163 case android.R.id.home:
164 NavUtils.navigateUpFromSameTask(this);
165 return true;
Roman Nurik19266f72012-03-12 21:48:47 -0700166 }
167 return super.onOptionsItemSelected(item);
168}
169</pre>
170
Scott Main7c840552013-03-26 18:53:01 -0700171<p>However, using {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
172navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current
173task</strong> (that is, the user began this task from your app). If that's not true and your
174activity was started in a task that belongs to a different app, then
175navigating <em>Up</em> should create a new task that belongs to your app, which
176requires that you create a new back stack.</p>
Roman Nurik19266f72012-03-12 21:48:47 -0700177
Scott Main7c840552013-03-26 18:53:01 -0700178<h3 id="BuildBackStack">Navigate up with a new back stack</h3>
179
180<p>If your activity provides any <a
181href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a>
182that allow other apps to start the
183activity, you should implement the {@link android.app.Activity#onOptionsItemSelected
184onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button
185after entering your activity from another app's task, your app starts a new task
186with 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
190whether the current activity instance exists in a different app's task. If
191it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}.
192Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
193navigateUpFromSameTask()} method as shown above.</p>
194
195<p>For example:</p>
Roman Nurik19266f72012-03-12 21:48:47 -0700196
197<pre>
198{@literal @}Override
199public boolean onOptionsItemSelected(MenuItem item) {
200 switch (item.getItemId()) {
Scott Main7c840552013-03-26 18:53:01 -0700201 // 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;
Roman Nurik19266f72012-03-12 21:48:47 -0700218 }
219 return super.onOptionsItemSelected(item);
220}
221</pre>
222
Scott Main7c840552013-03-26 18:53:01 -0700223<p class="note"><strong>Note:</strong> In order for the {@link
224android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()}
225method to work,
226you 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
228android:parentActivityName}</a> attribute (and corresponding <a
229href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data>}</a> element)
230as described above.</p>