better user interfaces with the android action bar
DESCRIPTION
User Interface, Android, ProgrammingTRANSCRIPT
(http://www.sitepoint.com) MENU
Mobile (http://www.sitepoint.com/mobile/)
The action bar is an important design element, usually at the top of each screen in an app, that provides a consistent familiar look betweenAndroid apps. It is used to provide better user interaction and experience by supporting easy navigation through tabs and dropdown lists. Italso provides a space for the app or activity’s identity, thus enabling the user to know their location in the app, and easy access to theactions that can be performed.
The action bar was introduced in Android 3.0, although support for older versions can be achieved by using the Android Support Library(http://developer.android.com/tools/supportlibrary/index.html). Before its release, the Options Menu was usually used to provide the actionsand functionality that are now put on the action bar. The action bar is included by default in all activities for apps with a minSdkVersion of11. You can disable it and opt to only use the options menu, but for better user experiences it’s better to use the action bar as it is visible tothe user, while the options menu needs the user to request it and the user might not be aware of its existence in the first place.
This tutorial explores setting up the action bar and discusses the different configurations that it offers.
Setting up the Action BarTo start off, we are going to create a new project. We won’t be using the Android Support Library, so make sure to select a minimum SDKversion of 11 or above. When you run your project, the action bar will be included at the top of your app’s screen. It is included in all activitiesthat use or inherit from the Theme.Holo (http://developer.android.com/reference/android/R.style.html#Theme_Holo) theme – which is thedefault when the minSdkVersion is set to 11 or greater. A typical action bar is shown in the following figure.
The action bar consists of:
App icon – This is used to identify your app with a logo or icon.View control – This can also be used to identify the app or the specific activity the user is on by the title. If your app has different views, itcan also be used to display these and allow for easy switching between views.Action buttons – These are used to display the most important and/or often used actions. If there isn’t enough space to show all of theaction buttons, those that don’t fit are automatically moved to the action overflow.Action overflow – This is used for the lesser used actions.
Adding Actions to the Action Bar
Better User Interfaces with the Android Action Bar
Published April 2, 2014
(http://www.sitepoint.com/author/jechessa/)
Joyce Echessa (http://www.sitepoint.com/author/jechessa/)
Tweet (Https://Twitter.Com/Share?Text=Better+User+Interfaces+With+The+Android+Action+Bar&Via=Sitepointdotcom)
Subscribe (Https://Confirmsubscription.Com/H/Y/1FD5B523FA48AA2B)
To add actions to the action bar, create a XML file in the res/menu directory where you will define each action. It is possible to define theactions in Java code, but you will write less code if you use XML. The contents of res/menu/main_activity_bar.xml are shown below. Inthis example, we’re using the Action Bar Icon Pack (http://developer.android.com/design/downloads/index.html#actionbariconpack) for theaction icons. Download it and copy the necessary icons to the res/drawable‐xxxx directory for the different screen densities.
Next, add the string literals to res/values/strings.xml , as shown below.
The icon attribute takes a resource ID for an image which will appear on the action bar with or without the title . To display the actiontitle add withText to showAsAction . For example you could use android:showAsAction="ifRoom|withText" to indicate that ifthere is room on the bar for the action button and text, they should both be shown. To force an action to always be displayed, use alwayson showAsAction . However, this is not advisable as it might cause undesirable layout effects on smaller screens. If you must, limit it to oneor two items.
You should always define the title attribute, even if you don’t want to display both the icon and title, for the following reasons:
The title will be used in the overflow if there isn’t enough space on the action bar for the action item.It might not be obvious to the user what the action item does just from its icon alone and so providing a title enables them to long press itto reveal a tooltip that displays the title.The title provides accessibility for sightimpaired users, as the screen reader can read the menu item’s title.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<menu xmlns:android="http://schemas.android.com/apk/res/android (http://schemas.android.com/apk/res/android)" >
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_record"
android:icon="@drawable/ic_action_video"
android:title="@string/action_record"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_save"
android:icon="@drawable/ic_action_save"
android:title="@string/action_save"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_label"
android:icon="@drawable/ic_action_new_label"
android:title="@string/action_label"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_play"
android:icon="@drawable/ic_action_play"
android:title="@string/action_play"
android:showAsAction="ifRoom" />
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:showAsAction="never" />
</menu>
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf‐8"?>
<resources>
<string name="app_name">ActionBar</string>
<string name="action_settings">Settings</string>
<string name="action_search">Search</string>
<string name="action_record">Record Video</string>
<string name="action_save">Save</string>
<string name="action_label">Add Label</string>
<string name="action_play">Play Video</string>
<string name="hello_world">Hello world!</string>
</resources>
Next, we need to implement the onCreateOptionsMenu() callback method in our activity. This inflates the menu resource into the givenMenu object for use in the action bar. The code for this function is shown below.
Run the project and you should see something similar to the following figure. Some action buttons appear on the action bar while the restcan be seen on the expanded action overflow. On changing to landscape view, the action bar automatically adapts to the new width anddisplays more actions according to the guidelines given in the XML file.
Splitting the Action BarSince the action items share the action bar real estate with the app icon and title, you might want to split the action bar so that the actionitems appear at the bottom of the screen. This will give them more space, and thus more items will be visible to the user. If there is enoughspace, for example on larger screens or in landscape mode, the action bar will not be split.
To split the action bar, add android:uiOptions="splitActionBarWhenNarrow" to each activity in your manifest file that you want to have asplit action bar. This only supports API level 14 and above. To add support for lower levels use the following meta‐data element.
1
2
3
4
5
6
7
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_bar, menu);
return super.onCreateOptionsMenu(menu);
}
1
2
3
4
5
6
7
<activity
android:name="com.example.actionbar.MainActivity"
android:label="@string/app_name"
android:uiOptions="splitActionBarWhenNarrow" >
<meta‐data android:name="android.support.UI_OPTIONS"
android:value="splitActionBarWhenNarrow" />
<intent‐filter>
Hiding the Action BarYou might not want to have the action bar visible at all times to the user. A common example to this is the Gallery app which hides the actionbar when the user is looking at an image and shows the action bar when they touch the image. To toggle action bar visibility on touch, addthe following to your activity file.
On running the application, you will be able to show/hide the action bar by tapping the screen. You will notice that the content on the screenchanges position with each show/hide. This is because when you hide/show the action bar, the activity resizes, affecting the content’s sizeand position. To prevent this, you should instead overlay the action bar as described next.
Overlaying the Action BarOverlaying the action bar provides a better hide/show experience since the activity doesn’t resize on each hide/show, allowing your contentto stay put. You can enable overlaying by setting android:windowActionBarOverlay to true in your theme file. You should be using theTheme.Holo (http://developer.android.com/reference/android/R.style.html#Theme_Holo) theme (or one of its descendants). If yourminSdkVersion was set to 11, this should be the case.
In res/values/styles.xml , add the following:
Run the application, and notice that the content on the screen doesn’t change position when the action bar is hidden and revealed.
8
9
10
11
12
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent‐filter>
</activity>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
toggleActionBar();
}
return true;
}
private void toggleActionBar() {
ActionBar actionBar = getActionBar();
if(actionBar != null) {
if(actionBar.isShowing()) {
actionBar.hide();
}
else {
actionBar.show();
}
}
}
1
2
3
4
5
6
7
8
9
<resources>
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!‐‐ Application theme. ‐‐>
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowActionBarOverlay">true</item>
</style>
</resources>
Adding the Up NavigationAll 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 logicalparent screen in the app’s hierarchy by pressing the Up button in the action bar. Starting in API level 14, you can declare the logical parentof each activity by specifying the android:parentActivityName attribute in the activity element in the manifest file. To support lowerversions, include the Support Library and specify the parent activity as the value for android.support.PARENT_ACTIVITY , matching theandroid:parentActivityName attribute.
We’ll add another activity to demonstrate this. Add another activity file called SecondActivity , as shown in the following code listing. Wecall setDisplayHomeAsUpEnabled() to allow Up navigation with the app icon in the action bar. This will add a leftfacing caret alongsidethe app icon. When it is pressed, the activity receives a call to onOptionsItemSelected() .
In res/layout/second_activity.xml , add the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.actionbar;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.second_activity_bar, menu);
return super.onCreateOptionsMenu(menu);
}
@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);
}
}
1
2
3
4
5
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android (http://schemas.android.com/apk/res/android)"
android:id="@+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
Next, add the following strings to res/values.strings.xml .
Then, create a resource file for the second activity’s action bar. Name this file res/menu/second_activity_bar.xml , and add the followingXML.
Next, add the activity to the manifest file:
Then, add a button to the main activity in res/layout/activity_main.xml :
Also, add the onClick handler in MainActivity.java . This function, shown below, will start the second activity when the button isclicked.
6
7
8
9
10
11
12
13
14
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world_again" />
</RelativeLayout>
1
2
3
<string name="hello_world_again">Hello world, again!</string>
<string name="second">Go To Second Activity</string>
<string name="second_activity_title">Second Activity</string>
1
2
3
4
5
6
7
<menu xmlns:android="http://schemas.android.com/apk/res/android (http://schemas.android.com/apk/res/android)" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
1
2
3
4
5
6
7
8
9
10
11
12
<application>
...
<activity
android:name="com.example.actionbar.SecondActivity"
android:label="@string/second_activity_title"
android:parentActivityName="com.example.actionbar.MainActivity" >
<meta‐data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.actionbar.MainActivity" />
</activity>
...
</application>
1
2
3
4
5
6
7
8
<Button
android:id="@+id/second"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/TextView1"
android:layout_centerVertical="true"
android:onClick="openSecondActivity"
android:text="@string/second" />
Run the application. There will be a button on the first screen that, when pressed, brings up a second screen with the action bar shownbelow. Notice the caret that navigates to the parent activity when clicked.
Action Bar InteractivitySo far we have created action items that do nothing when clicked on. Next we’ll see how to add some interactivity to the action bar.
Handling Clicks on Action ItemsWhen an action is clicked, the activity’s onOptionsItemSelected() method is called. The action can be identified by callinggetItemId() . Add the onOptionsItemSelected() method to MainActivity.java , as shown in the following example. Here we aredisplaying a different message when each action is clicked on.
Action ViewsAction views are interactive widgets that appear within the action bar as a substitute for action buttons. They allow occasionally used UIitems to be placed on the action bar, thus avoiding unnecessary consumption of screen space and switching of activities to use them.
1
2
3
4
public void openSecondActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
// Code you want run when activity is clicked
Toast.makeText(this, "Search clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_record:
Toast.makeText(this, "Record clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_save:
Toast.makeText(this, "Save clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_label:
Toast.makeText(this, "Label clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_play:
Toast.makeText(this, "Play clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
To declare an action view, use either the actionLayout or actionViewClass attribute to specify either a layout resource or widget classto use, respectively. As a quick example, to add a SearchView widget to our example, modify the search action inres/menu/main_activity_bar.xml as follows.
On running the application, an edit text view will appear when the search action is clicked on.
We will add our own custom view to the action bar. Create a layout file named res/layout/my_action.xml . This will be the custom view’slayout resource.
Then, add the action item to res/menu/main_activity_bar.xml , as shown below.
This will use the layout we added above. collapseActionView collapses the action view so that only the icon shows on the action bar andwhen clicked on, it expands to reveal an edit text view. Clicking on the Up caret exits from the action view.
Next, updated the main activity file, MainActivity.java , as shown below. Take note of the comments throughout the code.
1
2
3
4
5
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android (http://schemas.android.com/apk/res/android)"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/myActionTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Type here:"
android:gravity="right" />
<EditText
android:id="@+id/myActionEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left" />
</LinearLayout>
1
2
3
4
5
<item android:id="@+id/my_action"
android:icon="@drawable/ic_action_edit"
android:title="My Action"
android:showAsAction="ifRoom|collapseActionView"
android:actionLayout="@layout/my_action" />
1 package com.example.actionbar;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.MenuItemCompat.OnActionExpandListener;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements TextView.OnEditorActionListener {
private MenuItem myActionMenuItem;
private EditText myActionEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@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_bar, menu);
// Here we get the action view we defined
myActionMenuItem = menu.findItem(R.id.my_action);
View actionView = myActionMenuItem.getActionView();
// We then get the edit text view that is part of the action view
if(actionView != null) {
myActionEditText = (EditText) actionView.findViewById(R.id.myActionEditText);
if(myActionEditText != null) {
// We set a listener that will be called when the return/enter key is pressed
myActionEditText.setOnEditorActionListener(this);
}
}
// For support of API level 14 and below, we use MenuItemCompat
MenuItemCompat.setOnActionExpandListener(myActionMenuItem, new OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
if(myActionEditText != null) {
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
myActionEditText.setText("");
}
return true; // Return true to expand action view
}
});
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
toggleActionBar();
}
return true;
}
private void toggleActionBar() {
ActionBar actionBar = getActionBar();
if(actionBar != null) {
if(actionBar.isShowing()) {
actionBar.hide();
}
else {
actionBar.show();
}
}
}
public void openSecondActivity(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
// Code you want run when activity is clicked
Toast.makeText(this, "Search clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_record:
Toast.makeText(this, "Record clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_save:
Toast.makeText(this, "Save clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_label:
Toast.makeText(this, "Label clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_play:
Toast.makeText(this, "Play clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_settings:
Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show();
return true;
In this code, we get the edit text view in our action view layout myActionEditText and set a listener on it. We want an operation to bemade when the user types in some text and presses return. By default, when the user presses Return, the cursor goes to a new line. Wewant to instead collapse the action view and get the user’s input. This is done by the onEditorAction method which checks on the type ofkey event on the edit text view. If it is Enter, the text input is captured and displayed. Then, the action view is collapsed.
We set a listener on the action view with MenuItemCompat.setOnActionExpandListener to know when the view expands and collapses.MenuItemCompat is used to support older API versions.
By default, when the user enters text and leaves the action view, on expanding it again, the previous text is still visible. We useonMenuItemActionExpand() to remove any text before the action view expands so that the edit text view will be blank.
ConclusionThe action bar is an important design element and it can be used to greatly improve an app’s user experience. We have looked at someconfigurations you can use on the action bar for your app’s UI, but there are more out there. For more information, check out thedocumentation (http://developer.android.com/guide/topics/ui/actionbar.html). You can see the code (https://github.com/sitepointexamples/androidactionbar) used in this article on GitHub.
You might also like:
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(keyEvent != null) {
// When the return key is pressed, we get the text the user entered, display it and collapse the view
if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
CharSequence textInput = textView.getText();
// Do something useful with the text
Toast.makeText(this, textInput, Toast.LENGTH_SHORT).show();
MenuItemCompat.collapseActionView(myActionMenuItem);
}
}
return false;
}
}
(http://www.sitepoint.com/author/jechessa/)
Joyce Echessa (http://www.sitepoint.com/author/jechessa/)
I am a web developer who dabbles in mobile development from time to time. You can find me on Twitter @joyceechessa(https://twitter.com/joyceechessa) or visit my website (http://www.echessa.com/) to see what I’m up to.
(https://twitter.com/joyceechessa) (https://github.com/echessa) (https://plus.google.com/u/0/+JoyceEchessa)
Treasure! Free Mobile Design Resources (http://www.sitepoint.com/freemobiledesignresources/)
Course: Responsive Web Design: Key Concepts(https://learnable.com/courses/responsivewebdesignkeyconcepts2759?utm_source=sitepoint&utm_medium=relateditems&utm_content=rwdkeyconcepts)
12 Android Tutorials for Beginners (http://www.sitepoint.com/12androidtutorialsbeginners/)
No Reader comments
About
About us (/aboutus/)Advertise (/advertising)Press Room (/press)Legals (/legals)Feedback (mailto:[email protected])Write for Us (/writeforus)
Our Sites
Learnable (https://learnable.com)Reference (http://reference.sitepoint.com)Web Foundations (/webfoundations/)
Connect
(/feed) (/newsletter) (https://www.facebook.com/sitepoint)(http://twitter.com/sitepointdotcom) (https://plus.google.com/+sitepoint)
© 2000 – 2015 SitePoint Pty. Ltd.