• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &lt;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 &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>
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 &lt;meta-data>}</a> element)
213as described above.</p>
214