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

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

Реализация вкладок с использованием новых API

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

Вы можете напрямую использовать новые API-интерфейсы в этих конкретных классах (без сбоев на более ранних устройствах) из-за отложенной загрузки классов. Классы загружаются и инициализируются при первом доступе — при первом доступе к классу или первом доступе к одному из его статических полей или методов. Таким образом, пока вы не создаете экземпляры реализаций, специфичных для Honeycomb, на устройствах, предшествующих Honeycomb, виртуальная машина 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 :

Котлин

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

Ява

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 :

Котлин

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

Ява

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

Вам также следует прочитать