新しい API を抽象化する
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
アクションバー タブをアプリの最上位ナビゲーションのメインフォームとして使用したいとします。しかし、残念ながら 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 つの実装とその抽象基本クラス(またはインターフェース)をサポートするクラス構造の図を以下に示します。
図 1. 抽象基本クラスとバージョン固有の実装を含むクラス構造図
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
の実装を作成します。
関連ドキュメント
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-07-27 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-27 UTC。"],[],[],null,["# Abstract the new APIs\n\nSuppose you want to use [action bar tabs](/guide/topics/ui/actionbar#Tabs) as the primary form of top-level navigation in your application. Unfortunately, the [ActionBar](/reference/android/app/ActionBar) APIs are only available in Android 3.0 or later (API level 11+). Thus, if you want to distribute your application to devices running earlier versions of the platform, you need to provide an implementation that supports the newer API while providing a fallback mechanism that uses older APIs.\n\nIn this class, you build a tabbed user interface (UI) component that uses abstract classes with version-specific implementations to provide backward-compatibility. This lesson describes how to create an abstraction layer for the new tab APIs as the first step toward building the tab component.\n\nPrepare for abstraction\n-----------------------\n\n[Abstraction](https://en.wikipedia.org/wiki/Abstraction_(computer_science)) in the Java programming language involves the creation of one or more interfaces or abstract classes to hide implementation details. In the case of newer Android APIs, you can use abstraction to build version-aware components that use the current APIs on newer devices, and fallback to older, more compatible APIs on older devices.\n\nWhen using this approach, you first determine what newer classes you want to be able to use in a backward compatible way, then create abstract classes, based on the public interfaces of the newer classes. In defining the abstraction interfaces, you should mirror the newer API as much as possible. This maximizes forward-compatibility and makes it easier to drop the abstraction layer in the future when it is no longer necessary.\n\nAfter creating abstract classes for these new APIs, any number of implementations can be created and chosen at runtime. For the purposes of backward-compatibility, these implementations can vary by required API level. Thus, one implementation may use recently released APIs, while others can use older APIs.\n\nCreate an abstract tab interface\n--------------------------------\n\nIn order to create a backward-compatible version of tabs, you should first determine which features and specific APIs your application requires. In the case of top-level section tabs, suppose you have the following functional requirements:\n\n1. Tab indicators should show text and an icon.\n2. Tabs can be associated with a fragment instance.\n3. The activity should be able to listen for tab changes.\n\nPreparing these requirements in advance allows you to control the scope of your abstraction layer. This means that you can spend less time creating multiple implementations of your abstraction layer and begin using your new backward-compatible implementation sooner.\n\nThe key APIs for tabs are in [ActionBar](/reference/android/app/ActionBar) and [ActionBar.Tab](/reference/android/app/ActionBar.Tab). These are the APIs to abstract in order to make your tabs version-aware. The requirements for this example project call for compatibility back to Eclair (API level 5) while taking advantage of the new tab features in Honeycomb (API Level 11). A diagram of the class structure to support these two implementations and their abstract base classes (or interfaces) is shown below.\n\n**Figure 1.** Class diagram of abstract base classes and version-specific implementations.\n\nAbstract ActionBar.Tab\n----------------------\n\nGet started on building your tab abstraction layer by creating an abstract class representing a tab, that mirrors the [ActionBar.Tab](/reference/android/app/ActionBar.Tab) interface: \n\n### Kotlin\n\n```kotlin\nsealed class CompatTab(val tag: String) {\n ...\n abstract fun getText(): CharSequence\n abstract fun getIcon(): Drawable\n abstract fun getCallback(): CompatTabListener\n abstract fun getFragment(): Fragment\n\n abstract fun setText(text: String): CompatTab\n abstract fun setIcon(icon: Drawable): CompatTab\n abstract fun setCallback(callback: CompatTabListener): CompatTab\n abstract fun setFragment(fragment: Fragment): CompatTab\n ...\n}\n```\n\n### Java\n\n```java\npublic abstract class CompatTab {\n ...\n public abstract CompatTab setText(int resId);\n public abstract CompatTab setIcon(int resId);\n public abstract CompatTab setTabListener(\n CompatTabListener callback);\n public abstract CompatTab setFragment(Fragment fragment);\n\n public abstract CharSequence getText();\n public abstract Drawable getIcon();\n public abstract CompatTabListener getCallback();\n public abstract Fragment getFragment();\n ...\n}\n```\n\nYou can use an abstract class instead of an interface here to simplify the implementation of common features such as association of tab objects with activities (not shown in the code snippet).\n\nAbstract ActionBar tab methods\n------------------------------\n\nNext, define an abstract class that allows you to create and add tabs to an activity, like [ActionBar.newTab()](/reference/android/app/ActionBar#newTab()) and [ActionBar.addTab()](/reference/android/app/ActionBar#addTab(android.app.ActionBar.Tab)): \n\n### Kotlin\n\n```kotlin\nsealed class TabHelper(protected val activity: FragmentActivity) {\n ...\n\n abstract fun setUp()\n\n fun newTab(tag: String): CompatTab {\n // This method is implemented in a later lesson.\n }\n\n abstract fun addTab(tab: CompatTab)\n\n ...\n}\n```\n\n### Java\n\n```java\npublic abstract class TabHelper {\n ...\n\n public CompatTab newTab(String tag) {\n // This method is implemented in a later lesson.\n }\n\n public abstract void addTab(CompatTab tab);\n\n ...\n}\n```\n\nIn the next lessons, you create implementations for `TabHelper` and `CompatTab` that work across both older and newer platform versions.\n\n### You should also read\n\n- [Action Bar](/guide/topics/ui/actionbar)\n- [Action Bar Tabs](/guide/topics/ui/actionbar#Tabs)"]]