버전 인식 구성요소 사용

이제 TabHelperCompatTab 두 가지를 구현(하나는 Android 3.0 이상, 다른 하나는 이전 버전의 플랫폼을 위한 것)했으므로 구현을 활용할 차례입니다. 이 학습 과정에서는 이러한 구현 간 전환 로직과 버전 인식 레이아웃을 만들고 마지막으로 이전 버전과 호환되는 UI 구성요소를 사용하는 방법을 설명합니다.

전환 로직 추가

TabHelper 추상 클래스는 현재 기기의 플랫폼 버전에 기반하여 버전에 적합한 TabHelperCompatTab 인스턴스를 만드는 팩토리 역할을 합니다.

Kotlin

    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)의 경우 활동 레이아웃에 탭 콘텐츠 컨테이너와 함께 TabWidgetTabHost가 포함되어 있는지 확인해야 합니다.

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 객체를 가져오고 다음 코드를 사용하여 탭을 추가할 수 있습니다.

Kotlin

    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 사용)에서 실행되는 이전 버전과 호환되는 탭의 스크린샷 예