Создайте реализацию со старыми API.

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

Выберите альтернативное решение.

Наиболее сложной задачей при использовании новых функций пользовательского интерфейса с обеспечением обратной совместимости является выбор и реализация более старого (резервного) решения для старых версий платформы. Во многих случаях можно реализовать назначение этих новых компонентов пользовательского интерфейса, используя возможности старых фреймворков. Например:

  • Панели действий можно реализовать с помощью горизонтального LinearLayout содержащего кнопки-изображения, либо в виде пользовательских заголовков, либо в виде элементов в макете активности. Действия, выходящие за пределы области действия, можно отобразить под кнопкой «Меню» устройства.

  • Вкладки панели действий можно реализовать с помощью горизонтального LinearLayout содержащего кнопки, или с помощью элемента пользовательского интерфейса TabWidget .

  • Виджеты NumberPicker и Switch можно реализовать с помощью виджетов Spinner и ToggleButton соответственно.

  • Виджеты ListPopupWindow и PopupMenu можно реализовать с помощью виджетов PopupWindow .

Как правило, не существует универсального решения для переноса новых компонентов пользовательского интерфейса на старые устройства. Следует учитывать пользовательский опыт: на старых устройствах пользователи могут быть незнакомы с новыми шаблонами проектирования и компонентами пользовательского интерфейса. Необходимо подумать, как можно реализовать ту же функциональность, используя знакомые элементы. Во многих случаях это менее важно, если новые компоненты пользовательского интерфейса широко распространены в экосистеме приложения (например, панель действий) или если модель взаимодействия проста и интуитивно понятна (например, пролистывание представлений с помощью ViewPager ).

Реализуйте вкладки, используя более старые API.

Для создания более старой реализации вкладок панели действий можно использовать TabWidget и TabHost (хотя в качестве альтернативы можно использовать горизонтально расположенные виджеты Button ). Реализуйте это в классах TabHelperEclair и CompatTabEclair , поскольку эта реализация использует API, появившиеся не позднее Android 2.0 (Eclair).

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

В реализации CompatTabEclair свойства вкладки, такие как текст и значок вкладки, хранятся в переменных экземпляра, поскольку для обработки такого хранения отсутствует объект ActionBar.Tab :

Котлин

class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :
        CompatTab(tag) {

    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private var text: CharSequence? = null
    ...

    override fun setText(resId: Int): CompatTab {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.resources.getText(resId)
        return this
    }

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

Java

public class CompatTabEclair extends CompatTab {
    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private CharSequence text;
    ...

    public CompatTab setText(int resId) {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.getResources().getText(resId);
        return this;
    }

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

В реализации TabHelperEclair используются методы виджета TabHost для создания объектов TabHost.TabSpec и индикаторов вкладок:

Котлин

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

    private var tabHost: TabHost? = null
    ...

    override fun setUp() {
        // Our activity layout for pre-Honeycomb devices
        // must contain a TabHost.
        tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply {
            setup()
        }
    }

    override fun addTab(tab: CompatTab) {
        ...
        tabHost?.newTabSpec(tab.tag)?.run {
            setIndicator(tab.getText()) // And optional icon
            ...
            tabHost?.addTab(this)
        }
    }
    // The other important method, newTab() is part of
    // the base implementation.
}

Java

public class TabHelperEclair extends TabHelper {
    private TabHost tabHost;
    ...

    protected void setUp() {
        if (tabHost == null) {
            // Our activity layout for pre-Honeycomb devices
            // must contain a TabHost.
            tabHost = (TabHost) mActivity.findViewById(
                    android.R.id.tabhost);
            tabHost.setup();
        }
    }

    public void addTab(CompatTab tab) {
        ...
        TabSpec spec = tabHost
                .newTabSpec(tag)
                .setIndicator(tab.getText()); // And optional icon
        ...
        tabHost.addTab(spec);
    }

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

Теперь у вас есть две реализации CompatTab и TabHelper : одна работает на устройствах под управлением Android 3.0 или более поздней версии и использует новые API, а другая — на устройствах под управлением Android 2.0 или более поздней версии и использует старые API. В следующем уроке мы рассмотрим использование этих реализаций в вашем приложении.