Top Banner
Android Support Library: Using ActionBarCompat Christophe Beyls DevFest Belgium 2013
33

Android Support Library: Using ActionBarCompat

May 11, 2015

Download

Technology

cbeyls

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.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Android Support Library: Using ActionBarCompat

Android Support Library:Using ActionBarCompat

Christophe Beyls

DevFest Belgium 2013

Page 2: Android Support Library: Using ActionBarCompat

About the speaker

● Mobile developer living in Brussels.● Regular attendee of GTUG

and Café Numerique.● Developed Brussels Transports for Android

during my spare time.

@BladeCoderplus.google.com/+ChristopheBeyls

Page 3: Android Support Library: Using ActionBarCompat

Agenda

● Introduction to the support library● ActionBarCompat vs

ActionBarSherlock● Setup & detailed usage● Limitations & workarounds● Migrating from ActionBarSherlock to

ActionBarCompat● Bugs & fixes

Page 4: Android Support Library: Using ActionBarCompat

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

Page 5: Android Support Library: Using ActionBarCompat

The Android Support Library - Features

● General utility classes○ LocalBroadcastManager (message bus)○ LruCache (backport)○ LongSparseArray (backport)○ WakefulBroadcastReceiver

● New UI widgets○ ViewPager (+ PagerTabStrip, PagerTitleStrip)○ SlidingPaneLayout○ DrawerLayout

Page 6: Android Support Library: Using ActionBarCompat

ActionBarCompat

http://developer.android.com/guide/topics/ui/actionbar.html

● Introduced in may 2013 as part of the Android support library v18

● Requires & extends android-support-v4.jar● Provides ActionBar support for Android 2.1+

(API 7+)● Mimics the native ActionBar API

Page 7: Android Support Library: Using ActionBarCompat

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

Page 8: Android Support Library: Using ActionBarCompat

ActionBarCompat vs ActionBarSherlock

● Android 4+ styled overflow menu

Page 9: Android Support Library: Using ActionBarCompat

Behaviour

ActionBarCompat works in two different modes depending on the Android version.

● Android 2.1 to 3.2A 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.

Page 10: Android Support Library: Using ActionBarCompat

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 StudioAdd dependency to build.gradle:dependencies { compile "com.android.support:appcompat-v7:18.0.+" ...}

Page 11: Android Support Library: Using ActionBarCompat

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

Page 12: Android Support Library: Using ActionBarCompat

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>

Page 13: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivity

Make your Activities inherit from ActionBarActivity and use the support methods.

public class MyActivity extends ActionBarActivity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.content);

ActionBar bar = getSupportActionBar();bar.setDisplayHomeAsUpEnabled(true);bar.setTitle("Hello DevFest!");

...}

}

Page 14: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivity

ActionBar-related support methods● getSupportActionBar()● supportInvalidateOptionsMenu()● supportRequestWindowFeature() [not in ABS]● setSupportProgress()● setSupportProgressBarIndeterminateVisibility()● startSupportActionMode()

Never call the corresponding native methodsif you use ActionBarCompat!Always call these methods after super.onCreate()

Page 15: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivity

Example - Showing a Progress Barpublic class ProgressActivity extends ActionBarActivity {

...@Overrideprotected 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);

}}

Page 16: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivitySingle Fragment container

Typical codepublic class SingleFragmentActivity extends ActionBarActivity {

@Overrideprotected 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.

Page 17: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivitySingle Fragment container

Universal codepublic class SingleFragmentActivity extends ActionBarActivity {

@Overrideprotected 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();}

}}

Page 18: Android Support Library: Using ActionBarCompat

Usage - ActionBarActivitySingle 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" />

Page 19: Android Support Library: Using ActionBarCompat

Usage - Fragments

Just inherit from the standard Fragment class of the Support Library.

Page 20: Android Support Library: Using ActionBarCompat

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>

Page 21: Android Support Library: Using ActionBarCompat

Usage - Menus

Android 3+ menu items attributes:● showAsAction● actionLayout● actionViewClass● actionProviderClass

Page 22: Android Support Library: Using ActionBarCompat

Usage - Menus

2. Use static methods in MenuItemCompat for Android 3+ MenuItem methods.

@Overridepublic void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setHasOptionsMenu(true);

}

@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

inflater.inflate(R.menu.realtime, menu);

boolean hasInfoMessage = !TextUtils.isEmpty(message);menu.findItem(R.id.info_message).setVisible(hasInfoMessage)

.setEnabled(hasInfoMessage);

MenuItemCompat.setActionProvider(menu.findItem(R.id.share), new ShareActionProvider(getActivity()));

}

Page 23: Android Support Library: Using ActionBarCompat

Usage - Menus

Android 3+ MenuItem methods:● setActionProvider()● getActionProvider()● setActionView()● getActionView()● expandActionView()● collapseActionView()● isActionViewExpanded()● setOnActionExpandListener()● setShowAsAction()

Page 24: Android Support Library: Using ActionBarCompat

Migrating from ActionBarSherlockto ActionBarCompat

In 7 steps1. Styles resources

Theme.Sherlock.* ➔ Theme.AppCompat.*Widget.Sherlock.* ➔ Widget.AppCompat.*

2. SherlockActivity ➔ ActionBarActivity3. Sherlock*Fragment ➔ *Fragment4. requestWindowFeature() ➔

supportRequestWindowFeature()and move the call after super.onCreate()

Page 25: Android Support Library: Using ActionBarCompat

Migrating from ActionBarSherlockto ActionBarCompat

5. Remove references to the top-level android.R.id.content and use a custom top container layout instead.

6. Menu resourcesReplace the android: namespace with the app local namespace for Android 3+ attributes.

7. Menu items codeReplace the ActionBarSherlock MenuItemswith the native MenuItems+ MenuItemCompat static methods, if needed.

Page 26: Android Support Library: Using ActionBarCompat

Styling Bugs - Issue 58498

1. Too small tabs (on older devices)

Page 27: Android Support Library: Using ActionBarCompat

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>

Page 28: Android Support Library: Using ActionBarCompat

Styling Bugs

2. Landscape glitches (on older devices)

Page 29: Android Support Library: Using ActionBarCompat

2. Landscape glitches (on older devices)

Styling Bugs

Page 30: Android Support Library: Using ActionBarCompat

Styling Bugs

2. Landscape glitches - fix/res/values/styles.xml

<style name="AppTheme" parent="@style/Theme.AppCompat"> ... <item name="android:actionBarStyle"> @style/myapp_transparent_ActionBar</item> <item name="actionBarStyle">@style/myapp_ActionBar</item></style>

<style name="myapp_ActionBar" parent="@style/Widget.AppCompat.ActionBar"> ... <!-- AppCompat fixes for the compatibility ActionBar --> <item name="indeterminateProgressStyle"> @android:style/Widget.ProgressBar.Small</item></style>

Page 31: Android Support Library: Using ActionBarCompat

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.

Page 32: Android Support Library: Using ActionBarCompat

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

Page 33: Android Support Library: Using ActionBarCompat

The End

Thanks for watching!

@BladeCoder - plus.google.com/+ChristopheBeyls