Serwer proxy do nowych interfejsów API

Z tej lekcji dowiesz się, jak utworzyć podklasę abstrakcyjnych klas CompatTab i TabHelper oraz używać nowych interfejsów API. Aplikacja może używać tej implementacji na urządzeniach z wersją platformy, która je obsługuje.

Wdrażanie kart za pomocą 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. Dlatego dopóki nie utworzysz instancji implementacji specyficznej dla Honeycomb na urządzeniach starszych niż Honeycomb, maszyna wirtualna Dalvik nie wyrzuci żadnych wyjątków VerifyError.

Dobrą konwencją nazewnictwa w przypadku tej implementacji jest dodawanie nazwy kodu poziomu interfejsu API lub wersji platformy odpowiadającej interfejsom API wymaganym przez konkretne klasy. Na przykład implementację natywnej karty może zapewnić klasa CompatTabHoneycomb lub TabHelperHoneycomb, ponieważ korzystają one z interfejsów API dostępnych w Androidzie 3.0 (poziom API 11) lub nowszym.

Schemat klasy implementacji kart w Honeycomb.

Rysunek 1. Diagram klas dla implementacji kart w Honeycomb.

Wdrażanie CompatTabHoneycomb

CompatTabHoneycomb to implementacja abstrakcyjnej klasy CompatTab, której TabHelperHoneycomb używa do odwoływania się do poszczególnych kart. CompatTabHoneycomb po prostu przekazuje wszystkie wywołania metod do zawartego w nim 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 abstrakcyjnej klasy TabHelper, która pośredniczy w wywoływaniu metod do rzeczywistego obiektu ActionBar, uzyskanego z zawartej w nim klasy 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.
}

Przeczytaj też