In July 2013 Google announced ActionBarCompat as part of its support library package. This library makes it easy to use the Action Bar that have to support older devices. Many have waited for this to happen ever since the Action Bar was introduced with Honeycomb.
I, though, didn’t expect that to happen. After all, the Action Bar was announced long ago and we had ActionBarSherlock. So why all the sudden?
I have written multiple posts about ActionBarSherlock on this blog prior to this announcement. Those posts still get a lot of attention and search hits. But while the basic concepts still apply, any ActionBarSherloc specific parts are kind of deprecated
I strongly believe that you should use ActionBarCompat for all new projects that want to support older devices. It also might make sense to migrate existing projects. So read on to learn why you should migrate or use ActionBarCompat right away and how to migrate existing projects.
Why You Should Prefer ActionBarCompat Over ActionBarSherlock
There are many reasons why you should prefer ActionbarCompat over ActionbarSherlock.
First of all this project is by Google, is part of the Support Library and thus likely will support new Action Bar related stuff at the same time Google releases them with stock Android.
Another good reason and a proof for the previous point is that ActionBarCompat supports the Navigation Drawer pattern right out of the box, while ActionBarSherlock does not. Thus if you want to add this drawer to an existing project/app you should migrate.
The last and not least reason is, that the creator of ActionBarSherlock, Jake Wharton, announced on Google+ that further development of ActionBarSherlock has been stopped. ActionBarSherlock 4.4 is the last release and might get bug fixes – but there won’t be any new features:
While there may be a dot release or two in the coming weeks, version 4.4 is shaping up to be The Last Release™.
He’s not too sad either See this quote, Jake Wharton made on his blog about ActionBarSherlock being intended to be thrown away eventually:
This is the entire purpose of the library. It has been designed for this use case specifically. It has been deprecated from inception with the intention that you could some day throw it away.
To showcase how the migration works, I have migrated the sample project ActionViews to ActionBarCompat. This sample project shows how to use the Action Bar with older devices and as a special case how to use ActionViews within your Action Bar. You can find more information about ActionViews on my older post. While originally written with ActionBarSherlock in mind, you can easily transfer those code samples to ActionBarSherlock. The next sections show you how to adapt the code snippets to move from ActionBarSherlock to ActionBarCompat.
You can find the ActionViews sample project on bitbucket. If you like you can see all changes necessary for the ActionBarCompat migration by viewing the commit.
Of course you have to integrate ActionBarCompat in the IDE of your choice. I do not cover this here. Gabriele Mariotti has written an excellent post covering the IDE integration of ActionBarCompat. I originally developed this project using Eclipse – which is why I occasionally refer to Eclipse specific shortcuts or why I include an Eclipse dialog later on. But the core of this post is independent of the IDE you want to use.
How to Proceed
So I assume that you have removed ActionBarSherlock from the ActionViews project and added ActionBarCompat instead. After that your project should be plagued with errors. Which is not too surpising. In the next sections I will take you through all the steps needed to get the project deployable again.
I start with the resources and deal with code changes later on. Android’s Development Tools only generate a new
R.java file when the resources are error-free. And without a correct
R file your Java sources won’t compile properly. Thus I prefer to fix resources first.
Changing the Style
The first thing to do, is to correct the style. I have used an ActionBarSherlock style previously. This style has to change to the proper ActionBarCompat style. And as with ActionBarSherlock you have to use an ActionBarCompat style, otherwise you’ll get a RuntimeException at app start.
Change the style with the name
AppBaseTheme to use
Theme.AppCompat.Light.DarkActionBar as its parent:
<style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar"> <!-- nothing API level dependent yet --> </style>
Since you might forget this step in future projects – at least I’m prone to initially forget this step – here’s the Exception that you will see in logcat in that case. Having seen it here might help you to remember what to do about it.
E/AndroidRuntime( 1413): Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. E/AndroidRuntime( 1413): at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:111) E/AndroidRuntime( 1413): at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:58) E/AndroidRuntime( 1413): at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98) E/AndroidRuntime( 1413): at com.grokkingandroid.sampleapp.samples.actionbar.actionviews.BaseActivity.onCreate(BaseActivity.java:30)
The dev tools will highlight the attribute
android:textIsSelectable somewhere up in the file after you save it. That’s because the minimum API level of the project is SDK 7 and the attribute has only been introduced with SDK 11. You can safely ignore this. If you clean your project after some more fixes, this marker will disappear. You won’t get any problems with lower versions despite this.
Fixing the Menu Definitions
The next step is to correct the menu definition files. Older Android versions don’t know about the Action Bar and thus do not support those new xml attributes for the Action Bar. So you have to change all attributes with the name
android:actionLayout. The fix is easy. Simply change the namespace from
app and add this namespace.
For example for the file
menu_fragment_expandable.xml the new xml looks like this:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id= "@+id/actionViewLayout" app:actionLayout= "@layout/expandable_actionview_edittext" android:icon= "@drawable/ic_action_add_inverse" app:showAsAction= "ifRoom|collapseActionView" android:title= "@string/add_item"/> </menu>
I make the namespace known to the parser in line 3. I use this namespace for the Action Bar specific attributes in lines 6 and 8. This way ActionBarCompat can read those attributes and provide the correct appearance of the menu items.