新しい API をプロキシする

このレッスンでは、抽象クラス CompatTab および TabHelper をサブクラス化して、新しい API を使用する方法を説明します。アプリは、それらの API をサポートするプラットフォーム バージョンを実行するデバイスで、この実装を使用できます。

新しい API を使用するタブを実装する

新しい API を使用する CompatTabTabHelper の具象クラスは、プロキシ実装です。 前のレッスンで定義した抽象クラスは新しい API(クラス構造やメソッド署名など)を反映しているため、これらの新しい API を使用する具象クラスは、API の結果を呼び出すメソッドを単にプロキシするだけです。

遅延クラス読み込みのおかげで、これらの具象クラスでは新しい API を直接使用することができ、古いデバイスでもクラッシュしません。クラスは、最初のアクセスの際に(初めてクラスをインスタンス化するか、静的フィールドまたは静的メソッドの 1 つにアクセスするときに)読み込まれて初期化されます。したがって、Honeycomb より前のデバイスで Honeycomb 固有の実装をインスタンス化しない限り、Dalvik VM は VerifyError 例外をスローしません。

この実装では、具象クラスが必要とする API に対応する API レベルまたはプラットフォーム バージョンのコード名を末尾に追加する命名規則を採用することをおすすめします。たとえば、ネイティブタブの実装を CompatTabHoneycomb および TabHelperHoneycomb クラスで提供できます。これらのクラスは Android 3.0(API レベル 11)以降で使用可能な API に依存しているからです。

タブの Honeycomb 実装のクラスの図

図 1. タブの Honeycomb 実装のクラスの図

CompatTabHoneycomb を実装する

CompatTabHoneycomb は、TabHelperHoneycomb が個々のタブの参照に使用する CompatTab 抽象クラスの実装です。CompatTabHoneycomb は、それに含まれている ActionBar.Tab オブジェクトへのすべてのメソッド呼び出しを単純にプロキシします。

CompatTabHoneycomb の実装を開始するには、新しい ActionBar.Tab API を使用します。

Kotlin

    class CompatTabHoneycomb internal constructor(val activity: Activity, tag: String) :
            CompatTab(tag) {
        ...
        // The native tab object that this CompatTab acts as a proxy for.
        private var mTab: ActionBar.Tab =
                // Proxy to new ActionBar.newTab API
                activity.actionBar.newTab()

        override fun setText(@StringRes textId: Int): CompatTab {
            // Proxy to new ActionBar.Tab.setText API
            mTab.setText(textId)
            return this
        }

        ...
        // Do the same for other properties (icon, callback, etc.)
    }
    

Java

    public class CompatTabHoneycomb extends CompatTab {
        // The native tab object that this CompatTab acts as a proxy for.
        ActionBar.Tab mTab;
        ...

        protected CompatTabHoneycomb(FragmentActivity activity, String tag) {
            ...
            // Proxy to new ActionBar.newTab API
            mTab = activity.getActionBar().newTab();
        }

        public CompatTab setText(int resId) {
            // Proxy to new ActionBar.Tab.setText API
            mTab.setText(resId);
            return this;
        }

        ...
        // Do the same for other properties (icon, callback, etc.)
    }
    

TabHelperHoneycomb を実装する

TabHelperHoneycombTabHelper 抽象クラスの実装であり、それに含まれる Activity から取得される実際の ActionBar へのメソッド呼び出しをプロキシします。

TabHelperHoneycomb を実装して、ActionBar API へのメソッド呼び出しをプロキシします。

Kotlin

    class TabHelperHoneycomb internal constructor(activity: FragmentActivity) : TabHelper(activity) {

        private var mActionBar: ActionBar? = null

        override fun setUp() {
            mActionBar = mActionBar ?: mActivity.actionBar.apply {
                navigationMode = ActionBar.NAVIGATION_MODE_TABS
            }
        }

        override fun addTab(tab: CompatTab) {
            // Tab is a CompatTabHoneycomb instance, so its
            // native tab object is an ActionBar.Tab.
            mActionBar?.addTab(tab.getTab() as ActionBar.Tab)
        }
    }
    

Java

    public class TabHelperHoneycomb extends TabHelper {
        ActionBar actionBar;
        ...

        protected void setUp() {
            if (actionBar == null) {
                actionBar = activity.getActionBar();
                actionBar.setNavigationMode(
                        ActionBar.NAVIGATION_MODE_TABS);
            }
        }

        public void addTab(CompatTab tab) {
            ...
            // Tab is a CompatTabHoneycomb instance, so its
            // native tab object is an ActionBar.Tab.
            actionBar.addTab((ActionBar.Tab) tab.getTab());
        }

        // The other important method, newTab() is part of
        // the base implementation.
    }
    

関連ドキュメント