Используйте компонент с учетом версий

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

Добавьте логику переключения.

Абстрактный класс TabHelper выступает в качестве фабрики для создания экземпляров TabHelper и CompatTab , соответствующих версии платформы текущего устройства:

Котлин

sealed class TabHelper(protected val mActivity: FragmentActivity, protected val tag: String) {

    abstract fun setUp()

    abstract fun addTab(tab: CompatTab)

    // Usage is tabHelper.newTab("tag")
    fun newTab(tag: String): CompatTab =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                CompatTabHoneycomb(mActivity, tag)
            } else {
                CompatTabEclair(mActivity, tag)
            }

    companion object {
        // Usage is TabHelper.createInstance(activity)
        fun createInstance(activity: FragmentActivity): TabHelper =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    TabHelperHoneycomb(activity)
                } else {
                    TabHelperEclair(activity)
                }
    }
}

Java

public abstract class TabHelper {
    ...
    // Usage is TabHelper.createInstance(activity)
    public static TabHelper createInstance(FragmentActivity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return new TabHelperHoneycomb(activity);
        } else {
            return new TabHelperEclair(activity);
        }
    }

    // Usage is tabHelper.newTab("tag")
    public CompatTab newTab(String tag) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return new CompatTabHoneycomb(mActivity, tag);
        } else {
            return new CompatTabEclair(mActivity, tag);
        }
    }
    ...
}

Создайте макет действия с учетом версий.

Следующий шаг — предоставить макеты для вашей активности, которые поддерживают обе реализации вкладок. Для более старой реализации ( TabHelperEclair ) необходимо убедиться, что макет вашей активности содержит TabWidget и TabHost , а также контейнер для содержимого вкладок:

res/layout/main.xml:

<!-- This layout is for API level 5-10 only. -->
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp">

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>
</TabHost>

Для реализации TabHelperHoneycomb вам понадобится всего лишь FrameLayout для размещения содержимого вкладок, поскольку индикаторы вкладок предоставляются ActionBar :

res/layout-v11/main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabcontent"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Во время выполнения Android будет определять, какую версию макета main.xml следует загрузить в зависимости от версии платформы. Это та же логика, что и в предыдущем разделе, для определения того, какую реализацию TabHelper использовать.

Используйте TabHelper в своем действии.

В методе onCreate() вашего Activity вы можете получить объект TabHelper и добавить вкладки с помощью следующего кода:

Котлин

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    setContentView(R.layout.main)

    TabHelper.createInstance(this).apply {
        setUp()

        newTab("photos")
                .setText(R.string.tab_photos)
                .also { photosTab ->
                    addTab(photosTab)
                }

        newTab("videos")
                .setText(R.string.tab_videos)
                .also { videosTab ->
                    addTab(videosTab)
                }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.main);

    TabHelper tabHelper = TabHelper.createInstance(this);
    tabHelper.setUp();

    CompatTab photosTab = tabHelper
            .newTab("photos")
            .setText(R.string.tab_photos);
    tabHelper.addTab(photosTab);

    CompatTab videosTab = tabHelper
            .newTab("videos")
            .setText(R.string.tab_videos);
    tabHelper.addTab(videosTab);
}

При запуске приложения этот код создает корректную структуру активности и инициализирует либо объект TabHelperHoneycomb , либо TabHelperEclair . Конкретный используемый класс непрозрачен для активности, поскольку они используют общий интерфейс TabHelper .

Ниже представлены два скриншота, демонстрирующие работу этой реализации на устройствах с Android 2.3 и Android 4.0.

Пример работы вкладок на устройстве Android 2.3 (с использованием TabHelperEclair).
Пример работы вкладок на устройстве Android 4.0 (с использованием TabHelperHoneycomb).

Рисунок 1. Примеры скриншотов обратно совместимых вкладок, работающих на устройстве Android 2.3 (с использованием TabHelperEclair ) и устройстве Android 4.0 (с использованием TabHelperHoneycomb ).