A complete practical guide on how to implement an ActionBar for Android 2.1+ using the Android Support Library.
It also explains how to migrate to ActionBarCompat if you are already familiar with ActionBarSherlock.
Note: this presentation is suitable for AppCompat up to version 20. Instructions have changed a bit in the more recent versions.
3. Agenda
â Introduction to the support library
â ActionBarCompat vs
ActionBarSherlock
â Setup & detailed usage
â Limitations & workarounds
â Migrating from ActionBarSherlock to
ActionBarCompat
â Bugs & fixes
4. The Android Support Library - Features
Mandatory library for (almost) any kind of
Android project.
â Brings Fragments and Loaders to Android
1.6+
â Utility classes to use newer Android
features only if available
â TaskStackBuilder, NavUtils (navigation)
â NotificationCompat
â ShareCompat
5. The Android Support Library - Features
â General utility classes
â
â
â
â
LocalBroadcastManager (message bus)
LruCache (backport)
LongSparseArray (backport)
WakefulBroadcastReceiver
â New UI widgets
â ViewPager (+ PagerTabStrip, PagerTitleStrip)
â SlidingPaneLayout
â DrawerLayout
7. ActionBarCompat vs
ActionBarSherlock
Roughly similar to ActionBarSherlock, but:
â Supported & used by Google
â Makes your code cleaner with less
dependencies
â Produces a slightly smaller apk file
â Fully supports ActionBarDrawerToggle
9. Behaviour
ActionBarCompat works in two different
modes depending on the Android version.
â Android 2.1 to 3.2
A compatibility ActionBar will be used.
It is drawn inside the main content view.
â Android 4+
The native ActionBar will be used.
Method calls will be routed to the native
implementation.
10. Project Setup
Update Android Support Library to the latest version.
â Eclipse
Import library project from local folder:
[sdk]/extras/android/support/v7/appcompat
/android-support-v7-appcompat
â Android Studio
Add dependency to build.gradle:
dependencies {
compile "com.android.support:appcompat-v7:18.0.+"
...
}
11. Usage - Styles
First, make your app styles inherit from
ActionBarCompat styles.
/res/values/styles.xml
<style name="AppTheme" parent="@style/Theme.AppCompat">
...
</style>
â Theme.AppCompat
â Theme.AppCompat.Light
â Theme.AppCompat.Light.DarkActionBar
12. Usage - Styles
To customize the ActionBar appearance,
double-set each attribute in the theme.
<style name="AppTheme" parent="@style/Theme.AppCompat">
<item name="android:actionBarStyle">
@style/myapp_ActionBar</item>
<item name="actionBarStyle">@style/myapp_ActionBar</item>
</style>
<style name="myapp_ActionBar"
parent="@style/Widget.AppCompat.ActionBar">
<item name="android:background">
@drawable/custom_background</item>
<item name="background">@drawable/custom_background</item>
</style>
13. Usage - ActionBarActivity
Make your Activities inherit from
ActionBarActivity and use the support methods.
public class MyActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content);
ActionBar bar = getSupportActionBar();
bar.setDisplayHomeAsUpEnabled(true);
bar.setTitle("Hello DevFest!");
...
}
}
14. Usage - ActionBarActivity
ActionBar-related support methods
â getSupportActionBar()
â supportInvalidateOptionsMenu()
â supportRequestWindowFeature() [not in ABS]
â setSupportProgress()
â setSupportProgressBarIndeterminateVisibility()
â startSupportActionMode()
Never call the corresponding native methods
if you use ActionBarCompat!
Always call these methods after super.onCreate()
15. Usage - ActionBarActivity
Example - Showing a Progress Bar
public class ProgressActivity extends ActionBarActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.content);
ActionBar bar = getSupportActionBar();
bar.setDisplayHomeAsUpEnabled(true);
bar.setTitle("Hello DevFest!");
...
}
private void startLoading() {
setSupportProgressBarIndeterminateVisibility(true);
getSupportLoaderManager().initLoader(MY_LOADER_ID, null, myLoaderCallbacks);
}
}
16. Usage - ActionBarActivity
Single Fragment container
Typical code
public class SingleFragmentActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getSupportActionBar();
bar.setDisplayHomeAsUpEnabled(true);
bar.setTitle("Hello DevFest!");
if (savedInstanceState == null) {
MyFragment f = MyFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, f).commit();
}
}
}
â Will not work with ActionBarCompat.
17. Usage - ActionBarActivity
Single Fragment container
Universal code
public class SingleFragmentActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content);
ActionBar bar = getSupportActionBar();
bar.setDisplayHomeAsUpEnabled(true);
bar.setTitle("Hello DevFest!");
if (savedInstanceState == null) {
MyFragment f = MyFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(R.id.app_content, f).commit();
}
}
}
18. Usage - ActionBarActivity
Single Fragment container
Universal code
/res/layout/content.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/app_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
or just insert the fragment directly in your layout:
<fragment android:name="com.example.myapp.MyFragment"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
20. Usage - Menus
1. Define menus in resources as usual, but use the
app local namespace for Android 3+ attributes.
/res/menu/refresh.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/refresh"
android:icon="@drawable/action_refresh"
android:title="@string/refresh"
app:showAsAction="ifRoom"/>
</menu>
24. Migrating from ActionBarSherlock
to ActionBarCompat
In 7 steps
1. Styles resources
Theme.Sherlock.* â Theme.AppCompat.*
Widget.Sherlock.* â Widget.AppCompat.*
2. SherlockActivity â ActionBarActivity
3. Sherlock*Fragment â *Fragment
4. requestWindowFeature() â
supportRequestWindowFeature()
and move the call after super.onCreate()
25. Migrating from ActionBarSherlock
to ActionBarCompat
5. Remove references to the top-level android.
R.id.content and use a custom top
container layout instead.
6. Menu resources
Replace the android: namespace with the
app local namespace for Android 3+ attributes.
7. Menu items code
Replace the ActionBarSherlock MenuItems
with the native MenuItems
+ MenuItemCompat static methods, if needed.
26. Styling Bugs - Issue 58498
1. Too small tabs (on older devices)
27. Styling Bugs
1. Too small tabs - fix
/res/values/styles.xml
<style name="AppTheme" parent="@style/Theme.AppCompat">
...
<item name="android:actionBarTabStyle">
@style/myapp_ActionBarTabStyle</item>
<item name="actionBarTabStyle">@style/myapp_ActionBarTabStyle</item>
</style>
<style name="myapp_ActionBarTabStyle"
parent="@style/Widget.AppCompat.ActionBar.TabView">
...
<!-- AppCompat fix for the compatibility ActionBar -->
<item name="android:minWidth">107dp</item>
</style>
31. One more thingâŠ
Missing feature
No support for preference screens ?
â PreferenceActivity is mandatory to support
preference screens on older devices.
â There is no ActionBarPreferenceActivity, so:
â Either you get no ActionBar at all on the preferences
screen
â Or you create two preference activities and use a
native ActionBar on newer devices.
â You need to override the styles.
32. Missing feature
Alternative: use a custom PreferenceFragment
â I created a simple PreferenceFragment for
the support library.
â Based on the platformâs
PreferenceFragment with some reflection to
access a few protected methods.
â Works with ActionBarActivity.
â Source code can be found here:
https://gist.github.com/cbeyls
33. The End
Thanks for watching!
@BladeCoder - plus.google.com/+ChristopheBeyls