ActionBarSherlock is a library by Jake Wharton, that enables you to use action bars even on older devices without having to code an action bar from scratch. This library deals with all the details you do not want to care about. Even Googlers like Roman Nurik or Nick Butcher recommend to use this library and the Google IO app also makes use of this lib. So should you!

With this post I start my series about the action bar by simply adding an action bar to the project of my last post, adding some action items to it and explaining some basics of action bars. The focus of this post is mainly on getting ActionBarSherlock to run on your project. As such it is an introductory post about the action bar.

Since the action bar offers many functions and is the most important navigational component Android has, more posts about it will follow in the next weeks.

Getting ActionBarSherlock and adding it to Eclipse

The first thing you have to do, is to download the library from actionbarsherlock.com. After this unzip/untar it. The download contains three folders: library, samples and website. The samples folder contains four sample projects to showcase what you can do and to show you how to do it. You should have a look at them. The website folder contains the code of the project website. The library folder finally contains ActionBarSherlock’s source code.

Now go to Eclipse and add the ABS-library as an Android project. Do not use Eclipse’s import tool to import the ActionBarSherlock library – it would not work immediately and you would have to fix some settings. Instead use the project creation wizard of the Android Developer Tools.

Open File -> New -> Project -> Android Project From Existing Code.

Creating an Android project from existing source

In the next screen select the folder, which Eclipse then uses to search for projects. If you select the ActionBarSherlock root folder, Eclipse suggests a list of projects to create. Leave the “library” project checked and uncheck all others:

Select the library project

Click “Finish” to create the project.

Eclipse will now create a new project named “library”. I prefer a more useful name, so select the project called “library” and hit F2 to rename the project. I have renamed the project in Eclipse to “ActionBarSherlock”, so all following screens will refer to this name.

Adding the library to your project

Now that ABS is a library project you have to tell your own project to use it. I will use the project of my last post for this. Go to FragmentStarter’s project settings and switch to the Android tab.

If necessary scroll down until you see the Library panel. Click “Add”:

Adding libraries to an Android project

In the next window all available library projects will be listed. Select ActionBarSherlock and click “Ok”.

Select ActionBarSherlock from the list of libraries

When the window disappears the library should be listed in the library panel of the Android properties tab:

Check if the library has been added succesfully

What is slightly annoying is that the Android Developer Tools do not use the name of a project to reference it, but instead point to the directory itself. And what’s even more annoying is that a symlink gets translated to its real path, which is bound to change more often than a symlink.

Should you ever want to change the directory, you have to delete the reference to the library with the old path and link to the newly imported library. But unless you do a fresh install for blog posts, this probably won’t happen too often 🙂

That’s it. Your project bundles the lib from now on.

But wait a moment! If you have a look at your project, you will notice that it now sports a red warning icon. Go to the error tab and you will see lots of warnings. Eclipse states for Fragment, FragmentActivity and all the other classes of the support library, that they “cannot be resolved to a type”. Whoops!

Unknow type problems after adding ActionBarSherlock

The reason is, that ActionBarSherlock comes bundled with the library as well. And most of the time the support library added when following my post about fragments is different from the one bundled with ActionBarSherlock. In the console tab of Eclipse you see the message “Jar mismatch! Fix your dependencies” with the hashcodes of the mismatching files and where these files are stored:

[FragmentStarterProject] Found 2 versions of android-support-v4.jar in the dependency list,
[FragmentStarterProject] but not all the versions are identical (check is based on SHA-1 only at this time).
[FragmentStarterProject] All versions of the libraries must be the same at this time.
[FragmentStarterProject] Versions found are:
[FragmentStarterProject] Path: /opt/workspace/FragmentStarterProject/libs/android-support-v4.jar
[FragmentStarterProject] Length: 385685
[FragmentStarterProject] SHA-1: 48c94ae70fa65718b382098237806a5909bb096e
[FragmentStarterProject] Path: /opt/libs/ActionBarSherlock/library/libs/android-support-v4.jar
[FragmentStarterProject] Length: 349252
[FragmentStarterProject] SHA-1: 612846c9857077a039b533718f72db3bc041d389
[FragmentStarterProject] Jar mismatch! Fix your dependencies

To fix this, simply delete the support library from you project. Go to the libs folder, select the android-support-v4.jar file and delete it. You can still use the support library because it’s also part of the ABS project.

If you need a newer version of the support library than the one bundled with ActionBarSherlock, remove the support library from both projects and add it anew to the ActionBarSherlock project.

With this done your project is good again. The next step, of course, is to change some code.

Changing the types to their ActionBarSherlock counterparts

Just adding the library won’t magically add an action bar to your project. Instead you have to change some of your code.

The first thing you have to do, is to change the classes from which you inherit. Instead of Activity use SherlockActivity, instead of FragmentActivity use SherlockFragmentActivity, instead of Fragment use SherlockFragment and so on. Now do this for the two activities and the two fragments you created while reading the last post.

You will notice that the ItemDetailActivity won’t compile any more. Whenever you add ActionBarSherlock to an existing project, this is bound to happen. Why is that?

Have a look at the error message Eclipse is displaying: “Cannot override the final method from SherlockFragmentActivity”. The method is the following:

ActionBarSherlock overrides every method of it’s superclasses that takes either a Menu, MenuItem or MenuInflater object of the android.view package as parameter and declares those methods as final. You need to know that all the items in an action bar are actually menu items. Thus only by doing it this way ActionBarSherlock can take control of all the menu-handling and change it for older Android versions.

While the error message might sound bad, it actually isn’t. ActionBarSherlock provides
for every final method another method with the same name and the same number of arguments. Even the class names of the arguments are the same. Only the packages differ.

This way ActionBarSherlock makes migration of existing projects very easy. You can keep your methods and do not have to change and adjust any logic. Simply delete all import statements to the menu-related classes of the package android.view. After this hit Ctrl-O to optimize and correct the import statements and when Eclipse displays the list of imports to choose from, choose those of the ActionBarSherlock library:

Choose ActionBarSherlock’s classes for imports

If you do this for ItemDetailActivity the warnings disappear. Whenever you use Eclipse (or any other IDE for that matter) to generate the import statements for you, take care to select the types of the ActionBarSherlock library. Those all start with com.actionbarsherlock.

Now that your code looks fine, you should try to run the project. Whether this run is successful or not depends on the Android version of your device. If you run this code on a device with at least Android 4.0 everything runs fine. But not so on older devices. Here you will get a Force Close dialog due to an IllegalStateException:

java.lang.IllegalStateException:
You must use Theme.Sherlock,
Theme.Sherlock.Light,
Theme.Sherlock.Light.DarkActionBar,
or a derivative.

Gladly the exception is pretty specific: You have to use one of the Sherlock themes to get your project to run. ActionBarSherlock needs many definitions to get the action bar styled correctly. Thus it needs these styles and you have to use the ABS themes. You can use your own theme, of course, but you must use one of Sherlock’s themes as a base for yours. See the Sherlock theming guide for more information on this.

Since adding the action bar to older devices is the reason to use ActionBarSherlock in the first place, you have to change the theme. Change your AndroidManifest.xml file to use a Sherlock theme:

Note: I use icons from the icon pack “Android Developer Icons 2” of opoloo. The values I use for the android:icon attributes are specific to this icon pack. As soon as you want to try this code, you have to prepare icons that match this code or change the attribute value to fit your icons. See the appendix for more on this.

Only the xml file won’t suffice. You also need to override the onCreateOptionsMenu() method to inflate this file:

This is the result when you run the project again. Note the differences between the 2.1 device and the 4.2 device:

Action bar with icons running on a 2.1 device after pressing the menu buttonAction bar with icons running on a 4.2 device

The overflow menu

When you compare the screenshots of the previous section, you quickly understand what the so-called overflow menu is. This is the menu hidden behind the three dots are the far end of the action bar on modern devices.

Android shows as many items as it can directly on the action bar. But especially on phones the place for action items is quite limited. Thus Android shows all those items, that do not fit on the action bar directly, in the overflow menu. You can also tell Android to put items in the overflow menu regardless of the space. You can do so by using the value never for the attribute android:showAsAction of these items. More on this attribute later on.

The items of the overflow menu are only visible if you click the three dots on the right of the action bar or press the menu button on those devices that have such a button.

The three dots appear only on devices without a menu button. That’s the way to indicate to the user that more items are available and it’s also the only way how users can access these items. On devices with a menu button on the other hand you do not have any indicator, but users can always check if an overflow menu is present by clicking the menu key. I actually think the solution for devices without menu button is way better than the solution on devices with a menu button. On these latter devices users always have to guess if an overflow menu is present or not. Alas Samsung, the vendor that sells by far the most Android devices, still ships devices with menu buttons 🙁

Sort your items by importance so that the most important actions are visible all the time. Those actions are the ones your users are most likely to perform on this screen. Think thoroughly about the importance of each item.

Other items should always be in the overflow menu, no matter how much space is left. For example if your app has an about screen, or some license info for the open source libs you use (well, ActionBarSherlock for example) or some information about what has changed with the recent version, I would put all those items into the overflow menu – no matter how much screen estate you have left.

The Android design page has some more guidance on this on their action bar pattern page and also shows you roughly how many items fit on the screen for some selected devices.

Use the android:icon as well as the android:title attribute

As you can see the action bar shows only an icon for the “Add Items” action. But that doesn’t mean that you should neglect the strings. First of all these strings are used for screenreaders so that visually impaired people still can use your app. And secondly, if users do not understand an icon immediately, they can longpress those icons until a hint appears that displays the text. Of course this hint is no excuse for confusing icons!

Another thing to note. Overflow menu items show only text. But not so on older devices. There you see the icon and the text. So always provide values for android:icon and for android:title!

Use android:showAsAction to define the appearance of the action items

The item element of the xml file for the action bar can contain four attributes that are only relevant for the action bar: android:showAsAction, android:actionLayout, android:actionViewClass and android:actionProviderClass. Of these I describe only the frst here, the other three are a topic for an extra post.

You can use the attribute android:showAsAction to decide which icons to display and in which way. It can take the following five values:

Possible values for the android:showAsAction attribute

Value

Meaning

ifRoom

Display item if enough room is left for this item

always

Display this item, regardless of the existing place

never

This item is not displayed in the action bar directly but in the overflow menu

withText

Display the icon together with the title text

collapseActionView

Only relevant for collabsible action views – not covered in this post

As a rule of thumb you should always use ifRoom, if you want the icon to be part of your action bar and you should use never if you want the item to always be part of the overflow menu.

The Android documentation for menu resources explicitly urges you to use always with great care. You should use this attribute only if the element is absolutely necessary. If you use this on multiple items and the place in the action bar is too small to do this properly Android displays overlapping icons. In this case the items are even less accessible than those of the overflow menu.

While you have to pick one of the first three, you can combine these with the value withText. This value decides whether Android shows only the icon or the icon plus the text of the android:title attribute. But Android does show the text only, if enough room is left.

Action bar with multiple icons running on a 2.1 deviceAction bar with multiple icons running on a 4.2 device after selecting the overflow menu

As you can see on phones Android still only displays the icons. Note what happens on small devices that have no menu button. Android had to put the second item into the overflow menu because it had not enough place for it. On devices with a menu button the second item would be directly visible in the action bar.

This is what the same app looks like on a tablet:

Action bar with multiple icons and text running on a 4.2 tablet

Now the withText value makes a difference. While I like items to display text on tablets, it is very unusual. Have a look at other apps to see how they do it, before you decide whether to display text or not. But do not use text to gloss over weaknesses in your icon design.

Dealing with user input

So far you have created the action bar and made it look right. But when you click on an item, nothing happens.

What you have to do is to implement the onOptionsItemSelected() method. You do this as you always did for menu item selections:

Action bar interaction is like any other user interaction and all the usual rules about the UI thread apply. So don’t put any stuff in here that’s long-lasting. Use Loaders, AsyncTasks, IntentServices or whatever you prefer for the specific job to do the heavy lifting.

What’s next?

In this first part of the ActionBar tutorial you have changed your project so that your activities and fragments now inherit from ActionBarSherlock’s classes and then made it compile and run.

After this you added items to the action bar, learned about the overflow menu and about the ActionBar-related attributes of the menu xml files. But with this you barely scratched the surface of what the action bar covers.

According to the design guidelines the “action bar is one of the most important design elements you can implement”. No wonder it features all sorts of possibilities. And, yes, it brings with it some complexity as well. So there is more to the action bar than just this post.

In the next post I am goig to cover the different navigation types the action bar supports. After this I will write yet another post about the so-called contextual action bar.

Appendix

As mentioned all icons that I use are icons of opoloo’s Android Developers Icons 2. You have to either get this pack, create icons for yourself or download the “Action Bar Icon Pack” from the design site. The latter icon pack contains no “Add” icon, so you have to adapt the XML.

You can also use totally inappropriate icons and hassle with the design later on. For the sake of following this tutorial you could use something like @android:drawable/ic_menu_add. But you should never use these for anything else than for just getting on with this tutorial.

Great tutorial! I want to ask you one thing. When i delete the support.v4 library all the errors where fixed and the app runs perfect! This means that i can use sherlock library and change activity to sherlockActivity and so on , only when i want to use extra features which does not exist in pre Honeycomb? I am asking this because in the beginning i started changing all of my activities and fragments even though i didn’t want any extra feature.

I’m not sure, if I understand you correctly. The v4 support library is needed to use stuff that was only introduced later to earlier API versions. E.g. Loaders or Fragments. It also contains some classes that are useful no matter which API version you use but that are not part of the standard API (yet). For example the ViewPager.

ActionBarsherlock on the other hand is only needed if you want to use the ActionBar on older API levels as well.

Given the distribution of API levels that Google publishes regularly, I recommend to use both, ABS and the v4 support library.

ActionBars are a very established pattern that ease the creation of a recognizable UI. Users come to expect it for most kinds of apps.

And using the support library helps you keep the code unified. E.g. by using Fragments. And it is of course also a requirement for using ActionBarSherlock.

I use this lib in my project. i use 3 tab in actionbar. now i want to change the height of tab. i am not getting solution if you have plz tell me.. i try custom tab but actionbar tab height still not change.

Hi Wolfram Rittmeyer, I am trying to execute aerogear aerodoc android application, it requires ActionBarSherlock and I have add actionbarsherlock libary to my application as you have given instruction but it is showing red spot error and when I have gone with build path I have seen that it is indicating actionbarsherlock.jar is missing, I stucked kindly help me to sort out this problem

You should post questions like that on SO. And you should include a full description of your problem and all relevant source snippets that could be helpful (in your case the menu xml file (main.xml) you are inflating and all of the onCreateOptionsMenu() method).

And state what “gives error” means. Doesn’t compile? Throws exception during runtime? Be specific when posting questions like that. If you ask questions with enough details, you will usually get answers very fast on Stackoverflow.

Ok … i am sry …
i have error in main activity when i change the fragmentactivity to sherlockfragment activity ….

@override
Public boolean oncreateoptionmenu(menu menu) { (((((((((((((((error for all from on create to menu….))))))))))))))))
// inflate the menu;this adds items to the action bar if is present
getmenuinflater().inflate(R.menu.main, menu);
return true;

Would just like to say thank you for such a detailed and helpful tutorial. Been struggling with adding the Action Bar Sherlock, or just a Dependency Project to Eclipse in general. This was very helpful. Thank you again.

I’m glad I was of help. For new projects though, I would recommend to use ActionBarCompat. This library is made by Google and part of Google’s support package. I haven’t done any post about it yet and have no time to do one in the near future. Because Google now provides an official backwards compatibility library for the ActionBar, ActionBarSherlock will no longer get any updates.

The currently existing sample projects on Bitbucket and also all my future sample projects will make use of ActionBarCompat. Thus you might want to have a look at them to understand how to use ActionBarCompat.