blob: 40d0bd1005e7c08486d33596d2157a0a40701836 [file] [log] [blame]
page.title=Adding Action Buttons
page.tags=actionbar
helpoutsWidget=true
trainingnavtop=true
@jd:body
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#XML">Specify the Actions in XML</a></li>
<li><a href="#AddActions">Add the Actions to the Action Bar</a></li>
<li><a href="#Respond">Respond to Action Buttons</a></li>
<li><a href="#UpNav">Add Up Button for Low-level Activities</a></li>
</ol>
<h2>You should also read</h2>
<ul>
<li><a href="{@docRoot}training/implementing-navigation/ancestral.html">Providing Up
Navigation</a></li>
</div>
</div>
<p>The action bar allows you to add buttons for the most important action
items relating to the app's current
context. Those that appear directly in the action bar with an icon and/or text are known
as <em>action buttons</em>. Actions that can't fit in the action bar or aren't
important enough are hidden in the action overflow.</p>
<img src="{@docRoot}images/training/basics/actionbar-actions.png" height="100" alt=""/>
<p class="img-caption"><strong>Figure 1.</strong> An action bar with an action button
for Search and the action overflow, which reveals additional actions.</a>
<h2 id="XML">Specify the Actions in XML</h2>
<p>All action buttons and other items available in the action overflow are defined
in an XML <a
href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. To add
actions to the action bar, create a new XML file in your project's
{@code res/menu/} directory.</p>
<p>Add an {@code &lt;item>} element for each item you want to include in the action bar.
For example:</p>
<p class="code-caption">res/menu/main_activity_actions.xml</p>
<pre>
&lt;menu xmlns:android="http://schemas.android.com/apk/res/android" >
&lt;!-- Search, should appear as action button -->
&lt;item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom" /&gt;
&lt;!-- Settings, should always be in the overflow -->
&lt;item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:showAsAction="never" /&gt;
&lt;/menu&gt;
</pre>
<div class="sidebox">
<h3>Download action bar icons</h3>
<p>To best match the Android <a
href="{@docRoot}design/style/iconography.html#action-bar">iconography</a> guidelines, you should
use icons provided in the
<a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar Icon Pack</a>.</p>
</div>
<p>This declares that the Search action should appear as an action button when room
is available in the action bar, but the
Settings action should always appear in the overflow. (By default, all actions appear in the
overflow, but it's good practice to explicitly declare your design intentions for each action.)
<p>The {@code icon} attribute requires a resource ID for an
image. The name that follows {@code &#64;drawable/} must be the name of a bitmap image you've
saved in your project's {@code res/drawable/} directory. For example,
{@code "&#64;drawable/ic_action_search"} refers to {@code ic_action_search.png}.
Likewise, the {@code title} attribute uses a string resource that's defined by an XML
file in your project's {@code res/values/} directory, as discussed in <a
href="{@docRoot}training/basics/firstapp/building-ui.html#Strings">Building a Simple User
Interface</a>.
<p class="note"><strong>Note:</strong> When creating icons and other bitmap images for your app,
it's important that you provide multiple versions that are each optimized for a different screen
density. This is discussed more in the lesson about <a
href="{@docRoot}training/basics/supporting-devices/screens.html">Supporting Different Screens</a>.
<p><strong>If your app is using the Support Library</strong> for compatibility on versions
as low as Android 2.1, the {@code showAsAction} attribute is not available from
the {@code android:} namespace. Instead this attribute is provided by the Support Library
and you must define your own XML namespace and use that namespace as the attribute prefix.
(A custom XML namespace should be based on your app name, but it can be any
name you want and is only accessible within the scope of the file in which you declare it.)
For example:</p>
<p class="code-caption">res/menu/main_activity_actions.xml</p>
<pre>
&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
<strong>xmlns:yourapp="http://schemas.android.com/apk/res-auto"</strong> >
&lt;!-- Search, should appear as action button -->
&lt;item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
<strong>yourapp:showAsAction="ifRoom"</strong> /&gt;
...
&lt;/menu&gt;
</pre>
<h2 id="AddActions">Add the Actions to the Action Bar</h2>
<p>To place the menu items into the action bar, implement the
{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback
method in your activity to inflate the menu resource into the given {@link android.view.Menu}
object. For example:</p>
<pre>
&#64;Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
</pre>
<h2 id="Respond">Respond to Action Buttons</h2>
<p>When the user presses one of the action buttons or another item in the action overflow,
the system calls your activity's {@link android.app.Activity#onOptionsItemSelected
onOptionsItemSelected()} callback method. In your implementation of this method,
call {@link android.view.MenuItem#getItemId getItemId()} on the given {@link android.view.MenuItem} to
determine which item was pressed&mdash;the returned ID matches the value you declared in the
corresponding {@code &lt;item>} element's {@code android:id} attribute.</p>
<pre>
&#64;Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_settings:
openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
</pre>
<h2 id="UpNav">Add Up Button for Low-level Activities</h2>
<div class="figure" style="width:240px">
<img src="{@docRoot}images/ui/actionbar-up.png" width="240" alt="">
<p class="img-caption"><strong>Figure 4.</strong> The <em>Up</em> button in Gmail.</p>
</div>
<p>All screens in your app that are not the main entrance to your app
(activities that are not 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 action bar.</p>
<p>When running on Android 4.1 (API level 16) or higher, or when using {@link
android.support.v7.app.ActionBarActivity} from the Support Library, performing <em>Up</em>
navigation simply requires that you declare the parent activity in the manifest file and enable
the <em>Up</em> button for the action bar.</p>
<p>For example, here's how you can declare an activity's parent in the manifest:</p>
<pre>
&lt;application ... >
...
&lt;!-- The main/home activity (it has no parent activity) -->
&lt;activity
android:name="com.example.myfirstapp.MainActivity" ...>
...
&lt;/activity>
&lt;!-- A child of the main activity -->
&lt;activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
&lt;!-- Parent activity meta-data to support 4.0 and lower -->
&lt;meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
&lt;/activity>
&lt;/application>
</pre>
<p>Then enable the app icon as the <em>Up</em> button by calling
{@link android.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled()}:</p>
<pre>
{@literal @}Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_displaymessage);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// If your minSdkVersion is 11 or higher, instead use:
// getActionBar().setDisplayHomeAsUpEnabled(true);
}
</pre>
<p>Because the system now knows {@code MainActivity} is the parent activity for
{@code DisplayMessageActivity}, when the user presses the
<em>Up</em> button, the system navigates to
the parent activity as appropriate&mdash;you <strong>do not</strong> need to handle the
<em>Up</em> button's event.</p>
<p>For more information about up navigation, see
<a href="{@docRoot}training/implementing-navigation/ancestral.html">Providing Up
Navigation</a>.