Serwer proxy do nowych interfejsów API

Z tej lekcji dowiesz się, jak tworzyć klasyfikacje abstrakcyjne CompatTab i TabHelper oraz jak używać nowych interfejsów API. Twoja aplikacja może korzystać z tej implementacji na urządzeniach z obsługiwaną wersją platformy.

Wdrażanie kart przy użyciu nowych interfejsów API

Konkretne klasy dla CompatTab i TabHelper, które używają nowszych interfejsów API, są implementacją proxy. Klasy abstrakcyjne zdefiniowane w poprzedniej lekcji odzwierciedlają nowe interfejsy API (struktura klas, podpisy metod itp.), dlatego konkretne klasy korzystające z nowszych interfejsów API po prostu pośredniczą w wywołaniach metod i ich wynikach.

W tych konkretnych klasach możesz używać nowszych interfejsów API i nie powodować awarii na wcześniejszych urządzeniach z powodu leniwego wczytywania klas. Klasy są wczytywane i inicjowane przy pierwszym dostępie – inicjuje je lub uzyskuje dostęp do jednego z jej statycznych pól bądź metod. Jeśli więc nie utworzysz instancji implementacji typowej dla Honeycomb na urządzeniach sprzed Honeycomb, maszyna wirtualna Dalvik nie zgłosi żadnych wyjątków VerifyError.

Dobrą konwencją nazewnictwa w tej implementacji jest dodanie nazwy kodu poziomu interfejsu API lub wersji platformy do interfejsów API wymaganych przez konkretne klasy. Na przykład implementację karty natywnej mogą zapewnić klasy CompatTabHoneycomb i TabHelperHoneycomb, ponieważ bazują one na interfejsach API dostępnych w Androidzie 3.0 (poziom API 11) lub nowszym.

Schemat klasy implementacji kart w Honeycomb.

Rysunek 1. Schemat klasy implementacji kart w Honeycomb.

Wdrażanie CompatTabHoneycomb

CompatTabHoneycomb to implementacja klasy abstrakcyjnej CompatTab, której TabHelperHoneycomb używa do odwoływania się do poszczególnych kart. CompatTabHoneycomb po prostu przekierowuje wszystkie wywołania metod do zawartego w niej obiektu ActionBar.Tab.

Rozpocznij implementację CompatTabHoneycomb przy użyciu nowych interfejsów API ActionBar.Tab:

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.)
}

Implementacja TabHelperHoneycomb

TabHelperHoneycomb to implementacja klasy abstrakcyjnej TabHelper, która pośredniczy w wywołaniach metody w rzeczywistym obiekcie ActionBar uzyskanym z zawartego w niej elementu Activity.

Zaimplementuj wywołania metody TabHelperHoneycomb przez serwer proxy do interfejsu API ActionBar:

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.
}

Warto też przeczytać