Прокси-сервер для новых API

В этом уроке вы узнаете, как создать подклассы абстрактных классов CompatTab и TabHelper и использовать новые API. Ваше приложение может использовать эту реализацию на устройствах с версией платформы, которая их поддерживает.

Как реализовать вкладки с помощью новых API

Конкретные классы для CompatTab и TabHelper, использующие более новые API, являются реализацией прокси. Поскольку абстрактные классы, определенные на предыдущем уроке, отражают новые API (структуру классов, сигнатуры методов и т. д.), конкретные классы, использующие эти новые API, вызывают прокси-методы и получают их результаты.

Вы можете напрямую использовать новые API в этих конкретных классах, не опасаясь сбоев на устройствах с более ранними версиями ОС, благодаря ленивой загрузке классов. Классы загружаются и инициализируются при первом обращении – создании экземпляра класса или первом обращении к одному из его статических полей или методов. Таким образом, пока вы не создаете экземпляры реализаций, предназначенных для Honeycomb, на устройствах с более ранними версиями Android, виртуальная машина Dalvik не будет генерировать исключения VerifyError.

В этом случае рекомендуется добавлять к названию уровень API или кодовое название версии платформы, соответствующее API, которые требуются конкретным классам. Например, реализация нативных вкладок может быть предоставлена классами CompatTabHoneycomb и TabHelperHoneycomb, поскольку они полагаются на API, доступные в Android 3.0 (уровень API 11) или более поздней версии.

Диаграмма классов для реализации вкладок в Honeycomb.
Рисунок 1. Диаграмма классов для реализации вкладок в Honeycomb.

Реализация CompatTabHoneycomb

CompatTabHoneycomb – это реализация абстрактного класса CompatTab, который TabHelperHoneycomb использует для ссылки на отдельные вкладки. CompatTabHoneycomb передает все вызовы методов содержащемуся в нем объекту ActionBar.Tab.

Начните внедрять CompatTabHoneycomb с помощью новых 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.)
}

Реализовать TabHelperHoneycomb

TabHelperHoneycomb – это реализация абстрактного класса TabHelper, который передает вызовы методов фактическому объекту ActionBar, полученному из содержащегося в нем объекта Activity.

Реализуйте TabHelperHoneycomb, передавая вызовы методов в 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.
}

Также рекомендуем ознакомиться со следующими материалами: