このページは「はじめてのAndoid5プログラミング」(清水美樹著、工学社刊、2015年2月14日発売、 ISBN978-4-7775-1879-1)の著者によるの著者による関連情報です。
Androidの「新しい仕様」には、「古いAndroidに対応するようにするサポート・ライブラリ」も含まれます。SDKサンプルの多くがこのサポート・ライブラリを使って書かれています。 古いAndroidへの対応法と、新しいライブラリだけで書く方法を解説します。
Android5.0の新仕様の代表ともいえる「CardView」「RecyclerView」 は「android.support.v7」で始まるパッケージのクラスです。「v7」は「Android2.1」の意味で、Android2.1用のアプリでもこの仕様を使うことができます。 このような「Android.support.v?」(?はAPIバージョン)というパッケージ名のライブラリは、Androidの各バージョンの標準APIとは別の「サポート・ライブラリ」です。 たとえば別ページで解説した
「SDK添付サンプルのFloatingActionButtonBasic」では「com.android.support:support-v4:21.+」という サポート・ライブラリが導入されています。本書5-2節で行った通り「build.gradle(Module:Application)」と書かれているノードを開いて、 確かめてみましょう。
古いAndroidにはフラグメントをアクティビティ上に置くという考えがありませんでした。
そこで、古いAndroidでは「android.support.v4.app.Fragment」を「android.support.v4.app.FragmentActivity」
の上に置くという方法を取ります。
そこで、起動するアクティビティ(Android Studioでは「MainActivity」と命名される)は「Activity」ではなく 「FragmentActivity」を継承するようにします。
Android標準の「android.app.FragmentTransaction」に代えて「android.support.v4.app.FragmentTransaction」を用います。
また、「FragmentTransaction」を得るための「FragmentManager」も「android.support.v4.app.FragmentManager」です。
呼び出すメソッドは「FragmentActivity」が持っている「getSupportFragmentManager」です。
新しいAndroid「最新の仕様」を使った方法に戻すには、この「逆」を行います。
「フラグメント」を「android.support.v4.app.Fragment」から「android.app.Fragment」に戻すことを考えましょう。 上記のサンプル「FloatingActionButtonBasic」がちょうどその対象です。
実は最初にしなければならないのは、アプリの「ターゲット」です。
最小(もっとも古い)ターゲットを「フラグメント」登場以前に設定してあると、コンパイルエラーが出ます。
サンプルが「サポート・ライブラリ」を用いているということは、古いAndroidにも対応させようという意図があるのですから、 最小ターゲットは古いはずです。
アプリのターゲットは、「Android Studio」では「Gradleスクリプト」に記述されるようになりました。
Gradleスクリプトを開く方法は上記と同様「build.gradle(Module:Application)」と書かれているノードですが、 エディタ上での編集箇所が違います。フラグメントのAPIのほとんどは、クラス名は新旧同じで、パッケージ名が違うだけです。
そこで、インポート宣言で「android.support.v4.app」という
パッケージで宣言されているクラス名を「android.app」に変更すれば、APIの変更は完成です。
アクティビティのAPIも変更しなければなりません。「ふつうに戻す」という感じになります。 継承するアクティビティを「FragmentActivity」から「Activity」に戻します。 インポートするクラスは「android.support.v4.app.FragmentActivity」は不要になり、「android.app.Activity」のインポートが必要になります (普段はインポートされているクラスですが、サポート・ライブラリを使うアプリではインポートされていないことがあります)
上で説明したとおり、メソッド「getSupportFragmentManager」を「getFragmentManager」に書き換えます。
「ActionBarCompat-Basic」ではやたらにたくさんのサポート・ライブラリを導入していますが、 「アクション・バー」に必要なのは「com.android.support:support-v4:21.+」と「com.android.support:appcampat-v7:18.0.+」の2つです。
「ActionBarCompat」は古いAndroidでも動くように作ってあるサンプルですから、「GingerBread(Android2.3)」のエミュレーターで動かすことが できます。ただし、筆者が動かしてみたところ、サンプルの「テーマ」が白色系に設定されているため、 白色のアクション・バー・アイコンが見えないのではないかと思います。
応急措置として、「values/template-styles.xml」を開いてください。添え書きのないファイルです。
(「添え書き」については、「Androidプロジェクトの構造」で説明しています)
テーマの指定の最も基本的なところを変更します。「Theme.Light」と書いてあるところを「Theme」にします。昔のテーマは「Light」 を付加しなければ、黒基調のデザインになりました。
サンプル「ActionBarCompat-Basic」の「AndroidManifest.xml」を見てください。「android:theme」の値が「Theme.AppCompat」になっています。 これは、「サポート・ライブラリのアクション・バーを使うテーマ」を意味します。
これを修正して、普通のテーマにします。それは「AppTheme」という名前です。これを書いておけば、動かすAndroid OSの標準テーマになります。 最近のAndroid OSの標準テーマでは標準の「アクション・バー」を使うことになっていますから、これでOKです。
リソース・ファイル「menu/main.xml」を編集します。ここに書かれたメニュー・アイテムが、アクション・バー上ではアクション・ボタンになります。
アクションボタンの表示の優先順位を示す「showAsAction」の「名前空間」が「support」になっています。
これを「android:showAsAction」に変更します。エディタに「赤の波線」が表示されるようですが気にしないでください。「名前空間は supportにしたほうがいいんじゃないですか」という警告のようです。そのままでもコンパイル・エラーにはなりません。
名前空間「support」はXMLの最初に、名前空間「android」とともに記述されています。「support」の名前空間は使わないので、消去します。
「ActionBarCompat-Basic」のJavaプログラムは「MainActivity」だけです。いよいよ、これを編集します。
まず、サポート・ライブラリのクラスをインポートした宣言を削除します。MainActivityはサポート・クラスであるActionBarActivityを継承しています。これをやめて、普通の「Activity」を継承します。編集の 中で「android.app.Activity」をインポートすることになるでしょう。
基本的には、これで作業は終わりです。
しかし、サンプル「ActivityCompat-Basic」には、メニューアイテム(アクション・バー上ではアクション・ボタン)をXMLではなく Javaのコードで記述するサンプルがひとつあります。
メソッド「onCreateOptionsMenu」を見てください。リスト1の部分が、「Location」というメニューアイテムの作成と設定です。 インポートを削除したので、参照エラーになっているでしょう。
MenuItem locationItem = menu.add(0, R.id.menu_location, 0, R.string.menu_location); locationItem.setIcon(R.drawable.ic_action_location); MenuItemCompat.setShowAsAction(locationItem, MenuItem.SHOW_AS_ACTION_ALWAYS);
リスト1では、「MenuItemCompat」を用いる部分だけを書き換えます。標準のメニュー・アイテムでは直接setShowAsActionのメソッド を使えるからです。
locationItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
この実験により、古いAndroidでもアクション・バーを使えるようにするには、逆の手順を踏めばよいことがわかります。