diff options
Diffstat (limited to 'docs/html/training/implementing-navigation/ancestral.jd')
| -rw-r--r-- | docs/html/training/implementing-navigation/ancestral.jd | 199 |
1 files changed, 144 insertions, 55 deletions
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd index ac35e64..c3c7ef8 100644 --- a/docs/html/training/implementing-navigation/ancestral.jd +++ b/docs/html/training/implementing-navigation/ancestral.jd @@ -1,12 +1,7 @@ -page.title=Implementing Ancestral Navigation -parent.title=Implementing Effective Navigation -parent.link=index.html +page.title=Providing Up Navigation +page.tags="up navigation","NavUtils","TaskStackBuilder" trainingnavtop=true -previous.title=Implementing Lateral Navigation -previous.link=lateral.html -next.title=Implementing Temporal Navigation -next.link=temporal.html @jd:body @@ -15,8 +10,9 @@ next.link=temporal.html <h2>This lesson teaches you to:</h2> <ol> - <li><a href="#up">Implement <em>Up</em> Navigation</a></li> - <li><a href="#app-home">Properly Handle the Application Home Screen</a></li> + <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> @@ -38,87 +34,180 @@ next.link=temporal.html </div> -<p><em>Ancestral navigation</em> is up the application's information hierarchy, where the top of the hierarchy (or root) is the application's home screen. This navigation concept is described in <a href="{@docRoot}training/design-navigation/ancestral-temporal.html">Designing Effective Navigation</a>. This lesson discusses how to provide ancestral navigation using the <em>Up</em> button in the action bar.</p> +<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> -<h2 id="up">Implement <em>Up</em> Navigation</h2> +<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> -<p>When implementing ancestral navigation, all screens in your application that aren't the home screen should offer a means of navigating to the immediate parent screen in the hierarchy via the <em>Up</em> button in the action bar.</p> -<img src="{@docRoot}images/training/implementing-navigation-up.png" - alt="The Up button in the action bar." id="figure-up"> +<h2 id="SpecifyParent">Specify the Parent Activity</h2> -<p class="img-caption"><strong>Figure 1.</strong> The <em>Up</em> button in the action bar.</p> +<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/extras/support-library.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> -<p>Regardless of how the current screen was reached, pressing this button should always take the user to the same screen in the hierarchy.</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> -<p>To implement <em>Up</em>, enable it in the action bar in your activity's {@link android.app.Activity#onCreate onCreate()} method:</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>You should also handle <code>android.R.id.home</code> in {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()}. This resource is the menu item ID for the <em>Home</em> (or <em>Up</em>) button. To ensure that a specific parent activity is shown, <em>DO NOT</em> simply call {@link android.app.Activity#finish finish()}. Instead, use an intent such as the one described below.</p> +<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()) { - case android.R.id.home: - // This is called when the Home (Up) button is pressed - // in the Action Bar. - Intent parentActivityIntent = new Intent(this, MyParentActivity.class); - parentActivityIntent.addFlags( - Intent.FLAG_ACTIVITY_CLEAR_TOP | - Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(parentActivityIntent); - finish(); - return true; + // 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>When the current activity belongs to a task from a different application—for example if it was reached via an intent from another application—pressing <em>Up</em> should create a new task for the application with a synthesized back stack. This approach is described in <a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a> and the {@link android.support.v4.app.TaskStackBuilder} class reference.</p> +<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>The {@link android.support.v4.app.NavUtils} and {@link android.support.v4.app.TaskStackBuilder} classes in the <a href="{@docRoot}tools/extras/support-library.html">Android Support Package</a> provide helpers for implementing this behavior correctly. An example usage of these two helper classes is below:</p> +<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()) { - case android.R.id.home: - Intent upIntent = new Intent(this, MyParentActivity.class); - if (NavUtils.shouldUpRecreateTask(this, upIntent)) { - // This activity is not part of the application's task, so create a new task - // with a synthesized back stack. - TaskStackBuilder.from(this) - .addNextIntent(new Intent(this, MyGreatGrandParentActivity.class)) - .addNextIntent(new Intent(this, MyGrandParentActivity.class)) - .addNextIntent(upIntent) - .startActivities(); - finish(); - } else { - // This activity is part of the application's task, so simply - // navigate up to the hierarchical parent activity. - NavUtils.navigateUpTo(this, upIntent); - } - return true; + // 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> -<h2 id="app-home">Properly Handle the Application Home Screen</h2> - -<p>By default, the <em>Home</em> button in the action bar is interactive. Since it does not make much sense to navigate home—or up one level—while on the home screen, you should disable the button like so:</p> - -<pre> -getActionBar().setHomeButtonEnabled(false); -</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> |
