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

Теперь, когда у вас есть две реализации 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)
                }
    }
}

Ява

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() вашей активности вы можете получить объект 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)
                }
    }
}

Ява

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