アクションバー タブをアプリの最上位ナビゲーションのメインフォームとして使用したいとします。しかし、残念ながら ActionBar
API は Android 3.0 以降(API レベル 11 以上)でしか利用できません。したがって、古いバージョンのプラットフォームを実行するデバイスにアプリを配布する場合は、新しい API をサポートする実装を提供する一方で、古い API を使用する代替メカニズムも提供する必要があります。
このトレーニング クラスでは、バージョン固有の実装で抽象クラスを使用し、下位互換性を持つタブ付きユーザー インターフェース(UI)コンポーネントを構築します。このレッスンでは、タブ コンポーネントを構築するための最初のステップとして、新しいタブ API の抽象化レイヤを作成する方法について説明します。
抽象化の準備
Java プログラミング言語の抽象化では、実装の詳細を隠蔽する 1 つ以上のインターフェースまたは抽象クラスを作成します。新しい Android API の場合、抽象化を使用して、新しいデバイスでは最新の API を使用し、古いデバイスではより互換性が高い古い API を代替使用する、バージョン対応コンポーネントを構築できます。
このアプローチを採用する場合は、まず、下位互換性のある方法で使用できる新しいクラスを決定し、次に、新しいクラスの公開インターフェースに基づいて抽象クラスを作成します。抽象化インターフェースを定義する際に、できるだけ新しい API を反映させる必要があります。それにより、上位互換性が最大化され、不要になった抽象化レイヤを将来破棄することが容易になります。
こうした新しい API 用の抽象クラスを作成したら、実行時に任意の数の実装を作成して選択できるようになります。下位互換性を確保するため、必要な API レベルに応じて異なる実装を用意できます。つまり、ある実装では最近リリースされた API を使用し、他の実装では古い API を使用できます。
抽象タブ インターフェースの作成
下位互換性のあるタブのバージョンを作成するには、まず、アプリに必要な機能と API を決定します。たとえば、最上位セクションのタブの場合に、次の機能要件があるとします。
- タブ インジケーターにテキストとアイコンを表示する。
- タブをフラグメント インスタンスに関連付けることができる。
- アクティビティがタブの変更をリスニングできる。
上記の要件を事前に準備することで、抽象化レイヤの範囲を制御できます。それにより、抽象化レイヤの複数の実装を作成する時間が短縮され、下位互換性のある新しい実装をより早く使用できます。
タブの主要な API は ActionBar
と ActionBar.Tab
です。これらはタブをバージョン対応にするために抽象化する API です。このサンプル プロジェクトの要件では、Honeycomb(API レベル 11)の新しいタブ機能を利用しつつ、Eclair(API レベル 5)に対する下位互換性を維持することが求められます。この 2 つの実装とその抽象基本クラス(またはインターフェース)をサポートするクラス構造の図を以下に示します。
ActionBar.Tab の抽象化
タブ抽象化レイヤを構築するには、まず、ActionBar.Tab
インターフェースを反映した、タブを表す抽象クラスを作成します。
Kotlin
sealed class CompatTab(val tag: String) { ... abstract fun getText(): CharSequence abstract fun getIcon(): Drawable abstract fun getCallback(): CompatTabListener abstract fun getFragment(): Fragment abstract fun setText(text: String): CompatTab abstract fun setIcon(icon: Drawable): CompatTab abstract fun setCallback(callback: CompatTabListener): CompatTab abstract fun setFragment(fragment: Fragment): CompatTab ... }
Java
public abstract class CompatTab { ... public abstract CompatTab setText(int resId); public abstract CompatTab setIcon(int resId); public abstract CompatTab setTabListener( CompatTabListener callback); public abstract CompatTab setFragment(Fragment fragment); public abstract CharSequence getText(); public abstract Drawable getIcon(); public abstract CompatTabListener getCallback(); public abstract Fragment getFragment(); ... }
ここで、インターフェースの代わりに抽象クラスを使用すると、タブ オブジェクトとアクティビティの関連付け(コード スニペットには示されていません)などの一般的な機能を簡単に実装できます。
ActionBar タブメソッドの抽象化
次に、タブを作成して ActionBar.newTab()
や ActionBar.addTab()
などのアクティビティに追加するための抽象クラスを定義します。
Kotlin
sealed class TabHelper(protected val activity: FragmentActivity) { ... abstract fun setUp() fun newTab(tag: String): CompatTab { // This method is implemented in a later lesson. } abstract fun addTab(tab: CompatTab) ... }
Java
public abstract class TabHelper { ... public CompatTab newTab(String tag) { // This method is implemented in a later lesson. } public abstract void addTab(CompatTab tab); ... }
次のレッスンでは、新旧両方のプラットフォーム バージョンで動作する TabHelper
と CompatTab
の実装を作成します。