Eclipse ADT を ver.22 に更新して ActionBarSherlock の SherlockFragmentActivity から Android Support Library v7 の AppCompat の ActionBarActivity に乗り換えた時の話する
ハマりそうでハマらない少しハマる Android のお話です。例によって、先人たちのお陰でそこまでハマらずにすんだので
僕も後人のために記録を残しておこうと思います。
アジェンダ
- ADT の ver.22 への更新
- Android SDK Manager の更新
- Android Support Library v7 の AppCompat の導入
- ActionBarSherlock から ActionBarActivity への乗り換え
1. ADT の ver.22 への更新
Eclipse の Help > Install New Software... で ADT を更新します。特にハマることはありません。
2. Android SDK Manager の更新
ADT や Android SDK Manager の更新はたいてい何か起こるので様子見しておいたおかげで少しハマる程度で済みました。
なにやら依存関係があるみたいで全部一括で更新できないと思ったら
1回更新後に Android SDK Build-tools が新たに現れるようです。
2回更新したら基本的には R.java が生成されてエラーは消えるようです。
Eclipse ADT 22 のバージョンアップでは Android SDK Manager のアップデートは 2 回する。
※ ActionBarSherlock を使っている場合はライブラリプロジェクトから削除しないように!
AndroidManifest.xml や res フォルダの ActionBarSherlock 由来のエラーを消すまで R.java が生成されなくて
事例報告のないハマりポイントで時間を費やすことになるので注意です。
おまけ
Android Private Libraries というものが追加されて、 Properties > Java Build Path > Order and Export でAndroid Private Libraries にチェックがついていないとエラーになるようです。
(最近のバージョンは勝手にチェックがついているのでエラーにはならない?)
穀風: Eclipse ADT を Ver. 22 にしたら ClassNotFoundException が発生するようになった
3. Android Support Library v7 の AppCompat の導入
- Eclipse の File > Import... で Existing Android Code Into Workspace を選択して
<AndroidSDK>/extras/android/support/v7/appcompatをインポートして
android-support-v7-appcompat というプロジェクトを追加する。 - 自分のプロジェクトの Properties > Android > Library の Add から
android-support-v7-appcompat をライブラリプロジェクトとして追加する。
Support Library Setup | Android Developers
これで Android Support Library v7 の AppCompat の機能を使うことができます。
Support Library Features | Android Developers
Action Bar | Design Patterns | Android Developers
Action Bar | API Guide | Android Developers
ActionBar | Android Developers
ActionBarActivity | Android Developers
ShareActionProvider | Android Developers
4. ActionBarSherlock から ActionBarActivity への乗り換え
プロジェクトの Properties > Android > Library から ActionBarSherlock を削除します。すると ActionBarSherlock に依存していた部分がエラーになるので修正しましょう。
Activity
-public class MainActivity extends SherlockFragmentActivity { +public class MainActivity extends ActionBarActivity {SherlockFragmentActivity を ActionBarActivity を変えるだけでほとんどエラーが無くなります。
Theme
<activity android:name="com.wada811.devcamera.MainActivity" android:icon="@drawable/ic_launcher" android:label="@string/appName" - android:theme="@style/Theme.Sherlock.Light.DarkActionBar" > + android:theme="@style/Theme.AppCompat.Light.DarkActionBar" > </activity>テーマは Sherlock や Holo を AppCompat に変えないと以下のような例外が発生します。
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
[Android]ActionBarSherlockの背景色をカスタマイズする | DevAchieveで作ったカスタムスタイルも
Sherlock を AppCompat に置き換える必要があります。
<resources xmlns:android="http://schemas.android.com/apk/res/android"> - <style name="ActionBarCustomStyle" parent="@style/Widget.Sherlock.Light.ActionBar.Solid"> + <style name="ActionBarCustomStyle" parent="@style/Widget.AppCompat.Light.ActionBar.Solid"> <item name="background">@color/actionBar</item> <item name="backgroundSplit">@color/actionBar</item> <item name="backgroundStacked">@color/actionBar</item> <item name="titleTextStyle">@style/ActionBarCustomTitleStyle</item> </style> - <style name="ActionBarCustomTitleStyle" parent="@style/TextAppearance.Sherlock.Widget.ActionBar.Title"> - <item name="android:textColor">@color/abs__primary_text_holo_dark</item> + <style name="ActionBarCustomTitleStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"> + <item name="android:textColor">@color/white</item> <item name="android:textStyle">bold</item> </style> </resources>
おまけ
Theme.Sherlock.Light.NoActionBar や Theme.Holo.Light.NoActionBar はあって、Theme.AppCompat.Light.NoActionBar がないのはおかしいので自分で作った。
<style name="Theme.AppCompat.Light.NoActionBar" parent="@style/Theme.AppCompat.Light.DarkActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
Menu
@Override public boolean onCreateOptionsMenu(Menu menu){ - getSupportMenuInflater().inflate(R.menu.activity_main, menu); + getMenuInflater().inflate(R.menu.activity_main, menu); return true; }呼び出し側のコードは MenuInflater を取得するメソッドが変わります。
また、Menu や MenuItem は Android のものを使うようになります。
<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" > +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:support="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/infoButton" android:icon="@drawable/ic_menu_info" android:title="@string/info" - android:showAsAction="ifRoom"/> + support:showAsAction="ifRoom"/> </menu>showAsAction 属性が API Level 11 から導入されたため、
それ以前は showAsAction 属性が存在しないので名前空間を定義して指定する必要があります。
上ではわかりやすさのため support としていますが、どんな名前でもいいです。
Using XML attributes from the support library | Action Bar | Android Developers
R.attr#showAsAction | Android Developers