The ActionBar, now known as the App Bar, is a consistent navigation element that is standard throughout modern Android applications. The ActionBar can consist of:
Important to note is that prior to 3.0, there was no ActionBar. In 2013, Google announced a support library that provides much better compatibility for older versions and support for tabbed interfaces. Since most of the examples below depend on this support library, make sure to include the AppCompat library.
Every application unless otherwise specified has an ActionBar by default. The ActionBar by default now has just the title for the current activity.
The ActionBar title displayed at the top of the screen is governed by the AndroidManifest.xml
file within the activity
nodes. In the example below, the activity "FirstActivity" will have an ActionBar with the string value of the resource identified by @string/activity_name
. If the value of that resource is "Foo," the string displayed in the ActionBar for this activity will be "Foo." Note that the application
node can supply a android:label
that acts as the default for activities and components with no other specified label.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.codepath.example.simpleapp.FirstActivity"
android:label="@string/activity_name" >
</activity>
</application>
Change the android:label
or android:icon
to modify the ActionBar title or icon for a given activity or for the application as a whole. In any Java activity, you can also call getSupportActionBar()
to retrieve a reference to the ActionBar and modify or access any properties of the ActionBar at runtime:
ActionBar actionBar = getSupportActionBar(); // or getActionBar();
getSupportActionBar().setTitle("My new title"); // set the top title
String title = actionBar.getTitle().toString(); // get the title
actionBar.hide(); // or even hide the actionbar
supportActionBar.setTitle("My new title") // set the top title
val title = actionBar.getTitle().toString() // get the title
actionBar.hide() // or even hide the actionbar
You can also change many other properties of the ActionBar not covered here. See the Extended ActionBar Guide for more details.
In the new Android 5.0 material design guidelines, the style guidelines have changed to discourage the use of the icon in the ActionBar. Although the icon can be added back with:
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
supportActionBar.setDisplayShowHomeEnabled(true);
supportActionBar.setLogo(R.mipmap.ic_launcher);
supportActionBar.setDisplayUseLogoEnabled(true);
The above code results in:
You can read more about this on the material design guidelines which state: "The use of application icon plus title as a standard layout is discouraged on API 21 devices and newer."
When you want to add primary actions to the ActionBar, you add the items to the activity context menu and if properly specified, they will automatically appear at the top right as icons in the ActionBar.
An activity populates the ActionBar from within the onCreateOptionsMenu()
method:
public class MainActivity extends AppCompatActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
}
class MainActivity : AppCompatActivity {
override fun onCreateOptionsMenu(menu: Menu) : Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu);
return true;
}
}
Entries in the action bar are typically called actions. Use this method to inflate a menu resource that defines all the action items within a res/menu/menu_main.xml
file, for example:
<!-- Menu file for `activity_movies.xml` is located in a file
such as `res/menu/menu_movies.xml` -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/miCompose"
android:icon="@drawable/ic_compose"
app:showAsAction="ifRoom"
android:title="Compose">
</item>
<item
android:id="@+id/miProfile"
android:icon="@drawable/ic_profile"
app:showAsAction="ifRoom|withText"
android:title="Profile">
</item>
</menu>
You also should note that the xmlns:app
namespace must be defined in order to leverage the showAsAction
option. The reason is that a compatibility library is used to support the showAsAction="ifRoom"
option. This option is needed to show the item directly in the action bar as an icon. If there's not enough room for the item in the action bar, it will appear in the action overflow. If withText
is specified as well (as in the second item), the text will be displayed with the icon.
The above code results in two action icons being displayed:
Note: The above code refers to the @drawable/ic_compose
and @drawable/ic_profile
resources which would have to exist for this to compile. To generate ActionBar icons, be sure to use the Asset Studio in Android Studio. To create a new Android icon set, right click on a res/drawable
folder and invoke New -> Image Asset.
There are two ways to handle the click for an ActionBar item. The first approach is you can use the android:onClick
handler in the menu XML, similar to handling button clicks:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item1"
android:icon="@drawable/ic_compose"
android:onClick="onComposeAction"
app:showAsAction="ifRoom"
android:title="Compose">
</item>
</menu>
and then define the method onComposeAction
in the parent activity before attempting to run the application or an exception will be thrown for the missing method:
public class MainActivity extends AppCompatActivity {
public void onComposeAction(MenuItem mi) {
// handle click here
}
}
class MainActivity : AppCompatActivity {
fun onComposeAction(mi: MenuItem) {
// handle click here
}
}
The second approach is to use the onOptionsItemSelected()
method. Using the MenuItem passed to this method, you can identify the action by calling getItemId(). This returns the unique ID provided by the item tag's id attribute so you can perform the appropriate action:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.miCompose:
composeMessage();
return true;
case R.id.miProfile:
showProfileView();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle presses on the action bar items
when (item.getItemId()) {
R.id.miCompose -> {
composeMessage();
return true
}
R.id.miProfile -> {
showProfileView()
return true
}
else ->
return super.onOptionsItemSelected(item)
}
}
and then you can handle all the action buttons in this single method.
ToolBar was introduced in Android Lollipop, API 21 release and is the spiritual successor of the ActionBar. It's a ViewGroup
that can be placed anywhere in your layout. ToolBar's appearance can be more easily customized than the ActionBar.
ToolBar works well with apps targeted to API 21 and above. However, Android has updated the AppCompat support libraries so the ToolBar can be used on lower Android OS devices as well. In AppCompat, ToolBar is implemented in the android.support.v7.widget.Toolbar
class. Refer to the ToolBar Guide for more information.