4e2c9dc74b
Change-Id: I173e3690148e5de3020bfdca8087906faa56b13b
214 lines
8.5 KiB
Plaintext
214 lines
8.5 KiB
Plaintext
page.title=Providing Up Navigation
|
|
page.tags="up navigation","NavUtils","TaskStackBuilder"
|
|
|
|
trainingnavtop=true
|
|
|
|
@jd:body
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<h2>This lesson teaches you to:</h2>
|
|
<ol>
|
|
<li><a href="#SpecifyParent">Specify the Parent Activity</a></li>
|
|
<li><a href="#up">Add Up Action</a></li>
|
|
<li><a href="#NavigateUp">Navigate Up to Parent Activity</a></li>
|
|
</ol>
|
|
|
|
<h2>You should also read</h2>
|
|
<ul>
|
|
<li><a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Providing Ancestral and Temporal Navigation</a></li>
|
|
<li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
|
|
<li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
|
|
</ul>
|
|
|
|
<h2>Try it out</h2>
|
|
|
|
<div class="download-box">
|
|
<a href="http://developer.android.com/shareables/training/EffectiveNavigation.zip"
|
|
class="button">Download the sample app</a>
|
|
<p class="filename">EffectiveNavigation.zip</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<p>All screens in your app that are not the main entrance to your app (the "home" screen)
|
|
should offer the user a way to navigate to the logical parent screen in the app's hierarchy by
|
|
pressing the <em>Up</em> button in the <a
|
|
href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>.
|
|
This lesson shows you how to properly implement this behavior.</p>
|
|
|
|
<div class="note design">
|
|
<p><strong>Up Navigation Design</strong></p>
|
|
<p>The concepts and principles for <em>Up</em> navigation are described in <a
|
|
href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective
|
|
Navigation</a> and the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design
|
|
guide.</p>
|
|
</div>
|
|
|
|
|
|
<img src="{@docRoot}images/training/implementing-navigation-up.png" id="figure-up">
|
|
<p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p>
|
|
|
|
|
|
|
|
<h2 id="SpecifyParent">Specify the Parent Activity</h2>
|
|
|
|
<p>To implement <em>Up</em> navigation, the first step is to declare which activity is the
|
|
appropriate parent for each activity. Doing so allows the system to facilitate navigation patterns
|
|
such as <em>Up</em> because the system can determine the logical parent activity from
|
|
the manifest file.</p>
|
|
|
|
<p>Beginning in Android 4.1 (API level 16), you can declare the logical parent of each
|
|
activity by specifying the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
|
|
android:parentActivityName}</a> attribute
|
|
in the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
|
|
element.</p>
|
|
|
|
<p>If your app supports Android 4.0 and lower, include the
|
|
<a href="{@docRoot}tools/support-library/index.html">Support Library</a> with your app and
|
|
add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a>
|
|
element inside the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
|
|
<activity>}</a>. Then specify the parent activity as the value
|
|
for {@code android.support.PARENT_ACTIVITY}, matching the <a
|
|
href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
|
|
android:parentActivityName}</a> attribute.</p>
|
|
|
|
<p>For example:</p>
|
|
|
|
<pre>
|
|
<application ... >
|
|
...
|
|
<!-- The main/home activity (it has no parent activity) -->
|
|
<activity
|
|
android:name="com.example.myfirstapp.MainActivity" ...>
|
|
...
|
|
</activity>
|
|
<!-- A child of the main activity -->
|
|
<activity
|
|
android:name="com.example.myfirstapp.DisplayMessageActivity"
|
|
android:label="@string/title_activity_display_message"
|
|
android:parentActivityName="com.example.myfirstapp.MainActivity" >
|
|
<!-- Parent activity meta-data to support 4.0 and lower -->
|
|
<meta-data
|
|
android:name="android.support.PARENT_ACTIVITY"
|
|
android:value="com.example.myfirstapp.MainActivity" />
|
|
</activity>
|
|
</application>
|
|
</pre>
|
|
|
|
<p>With the parent activity declared this way, you can navigate <em>Up</em>
|
|
to the appropriate parent using the {@link android.support.v4.app.NavUtils} APIs, as shown in
|
|
the following sections.</p>
|
|
|
|
|
|
<h2 id="up">Add Up Action</h2>
|
|
|
|
<p>To allow <em>Up</em> navigation with the app icon in the action bar, call
|
|
{@link android.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}:</p>
|
|
|
|
<pre>
|
|
{@literal @}Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
...
|
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
|
}
|
|
</pre>
|
|
|
|
<p>This adds a left-facing caret alongside the app icon and enables it as an action button
|
|
such that when the user presses it, your activity receives a call to
|
|
{@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. The
|
|
ID for the action is {@code android.R.id.home}.</p>
|
|
|
|
|
|
|
|
<h2 id="NavigateUp">Navigate Up to Parent Activity</h2>
|
|
|
|
<p>To navigate up when the user presses the app icon, you can use the {@link
|
|
android.support.v4.app.NavUtils} class's static method,
|
|
{@link android.support.v4.app.NavUtils#navigateUpFromSameTask
|
|
navigateUpFromSameTask()}. When you call this method, it finishes the current activity and
|
|
starts (or resumes) the appropriate parent activity.
|
|
If the target parent activity is in the task's back stack, it is brought
|
|
forward as defined by {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}.</p>
|
|
|
|
<p>For example:</p>
|
|
|
|
<pre>
|
|
{@literal @}Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
// Respond to the action bar's Up/Home button
|
|
case android.R.id.home:
|
|
NavUtils.navigateUpFromSameTask(this);
|
|
return true;
|
|
}
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
</pre>
|
|
|
|
<p>However, using {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
|
|
navigateUpFromSameTask()} is suitable <strong>only when your app is the owner of the current
|
|
task</strong> (that is, the user began this task from your app). If that's not true and your
|
|
activity was started in a task that belongs to a different app, then
|
|
navigating <em>Up</em> should create a new task that belongs to your app, which
|
|
requires that you create a new back stack.</p>
|
|
|
|
|
|
<h3 id="BuildBackStack">Navigate up with a new back stack</h3>
|
|
|
|
<p>If your activity provides any <a
|
|
href="{@docRoot}guide/components/intents-filters.html#ifs">intent filters</a>
|
|
that allow other apps to start the
|
|
activity, you should implement the {@link android.app.Activity#onOptionsItemSelected
|
|
onOptionsItemSelected()} callback such that if the user presses the <em>Up</em> button
|
|
after entering your activity from another app's task, your app starts a new task
|
|
with the appropriate back stack before navigating up.</p>
|
|
|
|
<p>You can do so by first calling
|
|
{@link android.support.v4.app.NavUtils#shouldUpRecreateTask shouldUpRecreateTask()} to check
|
|
whether the current activity instance exists in a different app's task. If
|
|
it returns true, then build a new task with {@link android.support.v4.app.TaskStackBuilder}.
|
|
Otherwise, you can use the {@link android.support.v4.app.NavUtils#navigateUpFromSameTask
|
|
navigateUpFromSameTask()} method as shown above.</p>
|
|
|
|
<p>For example:</p>
|
|
|
|
<pre>
|
|
{@literal @}Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
// Respond to the action bar's Up/Home button
|
|
case android.R.id.home:
|
|
Intent upIntent = NavUtils.getParentActivityIntent(this);
|
|
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
|
|
// This activity is NOT part of this app's task, so create a new task
|
|
// when navigating up, with a synthesized back stack.
|
|
TaskStackBuilder.create(this)
|
|
// Add all of this activity's parents to the back stack
|
|
.addNextIntentWithParentStack(upIntent)
|
|
// Navigate up to the closest parent
|
|
.startActivities();
|
|
} else {
|
|
// This activity is part of this app's task, so simply
|
|
// navigate up to the logical parent activity.
|
|
NavUtils.navigateUpTo(this, upIntent);
|
|
}
|
|
return true;
|
|
}
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
</pre>
|
|
|
|
<p class="note"><strong>Note:</strong> In order for the {@link
|
|
android.support.v4.app.TaskStackBuilder#addNextIntentWithParentStack addNextIntentWithParentStack()}
|
|
method to work,
|
|
you must declare the logical parent of each activity in your manifest file, using the
|
|
<a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">{@code
|
|
android:parentActivityName}</a> attribute (and corresponding <a
|
|
href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element)
|
|
as described above.</p>
|